diff options
Diffstat (limited to 'tests/tcg')
771 files changed, 43241 insertions, 0 deletions
diff --git a/tests/tcg/Makefile b/tests/tcg/Makefile new file mode 100644 index 00000000..89e3342f --- /dev/null +++ b/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/tests/tcg/alpha/Makefile b/tests/tcg/alpha/Makefile new file mode 100644 index 00000000..2b1f03d0 --- /dev/null +++ b/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/tests/tcg/alpha/crt.s b/tests/tcg/alpha/crt.s new file mode 100644 index 00000000..31af8825 --- /dev/null +++ b/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/tests/tcg/alpha/hello-alpha.c b/tests/tcg/alpha/hello-alpha.c new file mode 100644 index 00000000..79892e65 --- /dev/null +++ b/tests/tcg/alpha/hello-alpha.c @@ -0,0 +1,5 @@ +int main (void) +{ +  write (1, "hello\n", 6); +  return 0; +} diff --git a/tests/tcg/alpha/test-cond.c b/tests/tcg/alpha/test-cond.c new file mode 100644 index 00000000..74adffaa --- /dev/null +++ b/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/tests/tcg/alpha/test-ovf.c b/tests/tcg/alpha/test-ovf.c new file mode 100644 index 00000000..01c80e75 --- /dev/null +++ b/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/tests/tcg/cris/.gdbinit b/tests/tcg/cris/.gdbinit new file mode 100644 index 00000000..5e8c1d32 --- /dev/null +++ b/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/tests/tcg/cris/Makefile b/tests/tcg/cris/Makefile new file mode 100644 index 00000000..d34bfd8f --- /dev/null +++ b/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/tests/tcg/cris/README b/tests/tcg/cris/README new file mode 100644 index 00000000..2e65a76f --- /dev/null +++ b/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/tests/tcg/cris/check_abs.c b/tests/tcg/cris/check_abs.c new file mode 100644 index 00000000..9770a8d9 --- /dev/null +++ b/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/tests/tcg/cris/check_addc.c b/tests/tcg/cris/check_addc.c new file mode 100644 index 00000000..facd1bea --- /dev/null +++ b/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/tests/tcg/cris/check_addcm.c b/tests/tcg/cris/check_addcm.c new file mode 100644 index 00000000..7928bc99 --- /dev/null +++ b/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/tests/tcg/cris/check_addi.s b/tests/tcg/cris/check_addi.s new file mode 100644 index 00000000..a00dec02 --- /dev/null +++ b/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/tests/tcg/cris/check_addiv32.s b/tests/tcg/cris/check_addiv32.s new file mode 100644 index 00000000..20ba25d2 --- /dev/null +++ b/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/tests/tcg/cris/check_addm.s b/tests/tcg/cris/check_addm.s new file mode 100644 index 00000000..efece9f5 --- /dev/null +++ b/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/tests/tcg/cris/check_addo.c b/tests/tcg/cris/check_addo.c new file mode 100644 index 00000000..3d8e789f --- /dev/null +++ b/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/tests/tcg/cris/check_addoq.c b/tests/tcg/cris/check_addoq.c new file mode 100644 index 00000000..ed509e27 --- /dev/null +++ b/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/tests/tcg/cris/check_addq.s b/tests/tcg/cris/check_addq.s new file mode 100644 index 00000000..e6f874f9 --- /dev/null +++ b/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/tests/tcg/cris/check_addr.s b/tests/tcg/cris/check_addr.s new file mode 100644 index 00000000..7f55cdc1 --- /dev/null +++ b/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/tests/tcg/cris/check_addxc.s b/tests/tcg/cris/check_addxc.s new file mode 100644 index 00000000..09c8355b --- /dev/null +++ b/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/tests/tcg/cris/check_addxm.s b/tests/tcg/cris/check_addxm.s new file mode 100644 index 00000000..7563494b --- /dev/null +++ b/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/tests/tcg/cris/check_addxr.s b/tests/tcg/cris/check_addxr.s new file mode 100644 index 00000000..7f55cdc1 --- /dev/null +++ b/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/tests/tcg/cris/check_andc.s b/tests/tcg/cris/check_andc.s new file mode 100644 index 00000000..a947b773 --- /dev/null +++ b/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/tests/tcg/cris/check_andm.s b/tests/tcg/cris/check_andm.s new file mode 100644 index 00000000..93858863 --- /dev/null +++ b/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/tests/tcg/cris/check_andq.s b/tests/tcg/cris/check_andq.s new file mode 100644 index 00000000..55aa7b06 --- /dev/null +++ b/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/tests/tcg/cris/check_andr.s b/tests/tcg/cris/check_andr.s new file mode 100644 index 00000000..61aa1dc3 --- /dev/null +++ b/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/tests/tcg/cris/check_asr.s b/tests/tcg/cris/check_asr.s new file mode 100644 index 00000000..0a02ae6f --- /dev/null +++ b/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/tests/tcg/cris/check_ba.s b/tests/tcg/cris/check_ba.s new file mode 100644 index 00000000..873a4086 --- /dev/null +++ b/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/tests/tcg/cris/check_bas.s b/tests/tcg/cris/check_bas.s new file mode 100644 index 00000000..11929d42 --- /dev/null +++ b/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/tests/tcg/cris/check_bcc.s b/tests/tcg/cris/check_bcc.s new file mode 100644 index 00000000..c57ffa6f --- /dev/null +++ b/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/tests/tcg/cris/check_bound.c b/tests/tcg/cris/check_bound.c new file mode 100644 index 00000000..e8831754 --- /dev/null +++ b/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/tests/tcg/cris/check_boundc.s b/tests/tcg/cris/check_boundc.s new file mode 100644 index 00000000..fb9e5bc9 --- /dev/null +++ b/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/tests/tcg/cris/check_boundr.s b/tests/tcg/cris/check_boundr.s new file mode 100644 index 00000000..5c50cc5f --- /dev/null +++ b/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/tests/tcg/cris/check_btst.s b/tests/tcg/cris/check_btst.s new file mode 100644 index 00000000..e39fc8f4 --- /dev/null +++ b/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/tests/tcg/cris/check_clearfv32.s b/tests/tcg/cris/check_clearfv32.s new file mode 100644 index 00000000..4e913602 --- /dev/null +++ b/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/tests/tcg/cris/check_clrjmp1.s b/tests/tcg/cris/check_clrjmp1.s new file mode 100644 index 00000000..45a7005e --- /dev/null +++ b/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/tests/tcg/cris/check_cmp-2.s b/tests/tcg/cris/check_cmp-2.s new file mode 100644 index 00000000..414d3705 --- /dev/null +++ b/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/tests/tcg/cris/check_cmpc.s b/tests/tcg/cris/check_cmpc.s new file mode 100644 index 00000000..267c9ba8 --- /dev/null +++ b/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/tests/tcg/cris/check_cmpm.s b/tests/tcg/cris/check_cmpm.s new file mode 100644 index 00000000..e4dde15b --- /dev/null +++ b/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/tests/tcg/cris/check_cmpq.s b/tests/tcg/cris/check_cmpq.s new file mode 100644 index 00000000..5469141c --- /dev/null +++ b/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/tests/tcg/cris/check_cmpr.s b/tests/tcg/cris/check_cmpr.s new file mode 100644 index 00000000..b30af7a5 --- /dev/null +++ b/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/tests/tcg/cris/check_cmpxc.s b/tests/tcg/cris/check_cmpxc.s new file mode 100644 index 00000000..b237a931 --- /dev/null +++ b/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/tests/tcg/cris/check_cmpxm.s b/tests/tcg/cris/check_cmpxm.s new file mode 100644 index 00000000..87ea5bf8 --- /dev/null +++ b/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/tests/tcg/cris/check_dstep.s b/tests/tcg/cris/check_dstep.s new file mode 100644 index 00000000..bd43b838 --- /dev/null +++ b/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/tests/tcg/cris/check_ftag.c b/tests/tcg/cris/check_ftag.c new file mode 100644 index 00000000..908773a3 --- /dev/null +++ b/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/tests/tcg/cris/check_gcctorture_pr28634-1.c b/tests/tcg/cris/check_gcctorture_pr28634-1.c new file mode 100644 index 00000000..45ecd159 --- /dev/null +++ b/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/tests/tcg/cris/check_gcctorture_pr28634.c b/tests/tcg/cris/check_gcctorture_pr28634.c new file mode 100644 index 00000000..a0c52549 --- /dev/null +++ b/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/tests/tcg/cris/check_glibc_kernelversion.c b/tests/tcg/cris/check_glibc_kernelversion.c new file mode 100644 index 00000000..07448722 --- /dev/null +++ b/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/tests/tcg/cris/check_hello.c b/tests/tcg/cris/check_hello.c new file mode 100644 index 00000000..fb403ba9 --- /dev/null +++ b/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/tests/tcg/cris/check_int64.c b/tests/tcg/cris/check_int64.c new file mode 100644 index 00000000..fc600176 --- /dev/null +++ b/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/tests/tcg/cris/check_jsr.s b/tests/tcg/cris/check_jsr.s new file mode 100644 index 00000000..10602378 --- /dev/null +++ b/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/tests/tcg/cris/check_lapc.s b/tests/tcg/cris/check_lapc.s new file mode 100644 index 00000000..9a6150b7 --- /dev/null +++ b/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/tests/tcg/cris/check_lsl.s b/tests/tcg/cris/check_lsl.s new file mode 100644 index 00000000..9e2ddd7c --- /dev/null +++ b/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/tests/tcg/cris/check_lsr.s b/tests/tcg/cris/check_lsr.s new file mode 100644 index 00000000..18fdbef9 --- /dev/null +++ b/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/tests/tcg/cris/check_lz.c b/tests/tcg/cris/check_lz.c new file mode 100644 index 00000000..69c2e6d4 --- /dev/null +++ b/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/tests/tcg/cris/check_mapbrk.c b/tests/tcg/cris/check_mapbrk.c new file mode 100644 index 00000000..1aff7622 --- /dev/null +++ b/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/tests/tcg/cris/check_mcp.s b/tests/tcg/cris/check_mcp.s new file mode 100644 index 00000000..e65ccddf --- /dev/null +++ b/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/tests/tcg/cris/check_mmap1.c b/tests/tcg/cris/check_mmap1.c new file mode 100644 index 00000000..b803f0c4 --- /dev/null +++ b/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/tests/tcg/cris/check_mmap2.c b/tests/tcg/cris/check_mmap2.c new file mode 100644 index 00000000..35139a0e --- /dev/null +++ b/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/tests/tcg/cris/check_mmap3.c b/tests/tcg/cris/check_mmap3.c new file mode 100644 index 00000000..34401fa0 --- /dev/null +++ b/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/tests/tcg/cris/check_movdelsr1.s b/tests/tcg/cris/check_movdelsr1.s new file mode 100644 index 00000000..300cc877 --- /dev/null +++ b/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/tests/tcg/cris/check_movecr.s b/tests/tcg/cris/check_movecr.s new file mode 100644 index 00000000..da8ec262 --- /dev/null +++ b/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/tests/tcg/cris/check_movei.s b/tests/tcg/cris/check_movei.s new file mode 100644 index 00000000..bbfa6333 --- /dev/null +++ b/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/tests/tcg/cris/check_movemr.s b/tests/tcg/cris/check_movemr.s new file mode 100644 index 00000000..88489dee --- /dev/null +++ b/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/tests/tcg/cris/check_movemrv32.s b/tests/tcg/cris/check_movemrv32.s new file mode 100644 index 00000000..53950abd --- /dev/null +++ b/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/tests/tcg/cris/check_moveq.c b/tests/tcg/cris/check_moveq.c new file mode 100644 index 00000000..80f2dff6 --- /dev/null +++ b/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/tests/tcg/cris/check_mover.s b/tests/tcg/cris/check_mover.s new file mode 100644 index 00000000..b4db595d --- /dev/null +++ b/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/tests/tcg/cris/check_moverm.s b/tests/tcg/cris/check_moverm.s new file mode 100644 index 00000000..eabc9588 --- /dev/null +++ b/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/tests/tcg/cris/check_movmp.s b/tests/tcg/cris/check_movmp.s new file mode 100644 index 00000000..7fc11f06 --- /dev/null +++ b/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/tests/tcg/cris/check_movpmv32.s b/tests/tcg/cris/check_movpmv32.s new file mode 100644 index 00000000..daf0970e --- /dev/null +++ b/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/tests/tcg/cris/check_movpr.s b/tests/tcg/cris/check_movpr.s new file mode 100644 index 00000000..eef9bdb4 --- /dev/null +++ b/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/tests/tcg/cris/check_movprv32.s b/tests/tcg/cris/check_movprv32.s new file mode 100644 index 00000000..d0d90e12 --- /dev/null +++ b/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/tests/tcg/cris/check_movscr.s b/tests/tcg/cris/check_movscr.s new file mode 100644 index 00000000..53c8ce6b --- /dev/null +++ b/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/tests/tcg/cris/check_movsm.s b/tests/tcg/cris/check_movsm.s new file mode 100644 index 00000000..7074336e --- /dev/null +++ b/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/tests/tcg/cris/check_movsr.s b/tests/tcg/cris/check_movsr.s new file mode 100644 index 00000000..d1889a7a --- /dev/null +++ b/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/tests/tcg/cris/check_movucr.s b/tests/tcg/cris/check_movucr.s new file mode 100644 index 00000000..7c8487d1 --- /dev/null +++ b/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/tests/tcg/cris/check_movum.s b/tests/tcg/cris/check_movum.s new file mode 100644 index 00000000..038e5394 --- /dev/null +++ b/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/tests/tcg/cris/check_movur.s b/tests/tcg/cris/check_movur.s new file mode 100644 index 00000000..3ecf475f --- /dev/null +++ b/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/tests/tcg/cris/check_mulv32.s b/tests/tcg/cris/check_mulv32.s new file mode 100644 index 00000000..f3793587 --- /dev/null +++ b/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/tests/tcg/cris/check_mulx.s b/tests/tcg/cris/check_mulx.s new file mode 100644 index 00000000..d43241a6 --- /dev/null +++ b/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/tests/tcg/cris/check_neg.s b/tests/tcg/cris/check_neg.s new file mode 100644 index 00000000..963c4b6f --- /dev/null +++ b/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/tests/tcg/cris/check_not.s b/tests/tcg/cris/check_not.s new file mode 100644 index 00000000..33bcf155 --- /dev/null +++ b/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/tests/tcg/cris/check_openpf1.c b/tests/tcg/cris/check_openpf1.c new file mode 100644 index 00000000..fdcf4c5c --- /dev/null +++ b/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/tests/tcg/cris/check_openpf2.c b/tests/tcg/cris/check_openpf2.c new file mode 100644 index 00000000..5d56189f --- /dev/null +++ b/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/tests/tcg/cris/check_openpf3.c b/tests/tcg/cris/check_openpf3.c new file mode 100644 index 00000000..557adee9 --- /dev/null +++ b/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/tests/tcg/cris/check_openpf4.c b/tests/tcg/cris/check_openpf4.c new file mode 100644 index 00000000..8bbee41a --- /dev/null +++ b/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/tests/tcg/cris/check_openpf5.c b/tests/tcg/cris/check_openpf5.c new file mode 100644 index 00000000..1f86ea28 --- /dev/null +++ b/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/tests/tcg/cris/check_orc.s b/tests/tcg/cris/check_orc.s new file mode 100644 index 00000000..c733f036 --- /dev/null +++ b/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/tests/tcg/cris/check_orm.s b/tests/tcg/cris/check_orm.s new file mode 100644 index 00000000..ee723a6a --- /dev/null +++ b/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/tests/tcg/cris/check_orq.s b/tests/tcg/cris/check_orq.s new file mode 100644 index 00000000..5060edc7 --- /dev/null +++ b/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/tests/tcg/cris/check_orr.s b/tests/tcg/cris/check_orr.s new file mode 100644 index 00000000..a514c11b --- /dev/null +++ b/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/tests/tcg/cris/check_ret.s b/tests/tcg/cris/check_ret.s new file mode 100644 index 00000000..b44fb259 --- /dev/null +++ b/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/tests/tcg/cris/check_scc.s b/tests/tcg/cris/check_scc.s new file mode 100644 index 00000000..4a8674cc --- /dev/null +++ b/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/tests/tcg/cris/check_settls1.c b/tests/tcg/cris/check_settls1.c new file mode 100644 index 00000000..69d20265 --- /dev/null +++ b/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/tests/tcg/cris/check_sigalrm.c b/tests/tcg/cris/check_sigalrm.c new file mode 100644 index 00000000..39fa8d9b --- /dev/null +++ b/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/tests/tcg/cris/check_stat1.c b/tests/tcg/cris/check_stat1.c new file mode 100644 index 00000000..2e2cae51 --- /dev/null +++ b/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/tests/tcg/cris/check_stat2.c b/tests/tcg/cris/check_stat2.c new file mode 100644 index 00000000..e36172ed --- /dev/null +++ b/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/tests/tcg/cris/check_stat3.c b/tests/tcg/cris/check_stat3.c new file mode 100644 index 00000000..36a9d5d2 --- /dev/null +++ b/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/tests/tcg/cris/check_stat4.c b/tests/tcg/cris/check_stat4.c new file mode 100644 index 00000000..04f21fe7 --- /dev/null +++ b/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/tests/tcg/cris/check_subc.s b/tests/tcg/cris/check_subc.s new file mode 100644 index 00000000..e34b5448 --- /dev/null +++ b/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/tests/tcg/cris/check_subm.s b/tests/tcg/cris/check_subm.s new file mode 100644 index 00000000..e07ea02d --- /dev/null +++ b/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/tests/tcg/cris/check_subq.s b/tests/tcg/cris/check_subq.s new file mode 100644 index 00000000..9e34fa31 --- /dev/null +++ b/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/tests/tcg/cris/check_subr.s b/tests/tcg/cris/check_subr.s new file mode 100644 index 00000000..742fbc89 --- /dev/null +++ b/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/tests/tcg/cris/check_swap.c b/tests/tcg/cris/check_swap.c new file mode 100644 index 00000000..f851cbce --- /dev/null +++ b/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/tests/tcg/cris/check_time1.c b/tests/tcg/cris/check_time1.c new file mode 100644 index 00000000..3fcf0e15 --- /dev/null +++ b/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/tests/tcg/cris/check_time2.c b/tests/tcg/cris/check_time2.c new file mode 100644 index 00000000..20b69b4f --- /dev/null +++ b/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/tests/tcg/cris/check_xarith.s b/tests/tcg/cris/check_xarith.s new file mode 100644 index 00000000..80038b2a --- /dev/null +++ b/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/tests/tcg/cris/crisutils.h b/tests/tcg/cris/crisutils.h new file mode 100644 index 00000000..3456b9d5 --- /dev/null +++ b/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/tests/tcg/cris/crt.s b/tests/tcg/cris/crt.s new file mode 100644 index 00000000..af027d74 --- /dev/null +++ b/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/tests/tcg/cris/sys.c b/tests/tcg/cris/sys.c new file mode 100644 index 00000000..551c5dd7 --- /dev/null +++ b/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/tests/tcg/cris/sys.h b/tests/tcg/cris/sys.h new file mode 100644 index 00000000..c5f88e1a --- /dev/null +++ b/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/tests/tcg/cris/testutils.inc b/tests/tcg/cris/testutils.inc new file mode 100644 index 00000000..aa1641b2 --- /dev/null +++ b/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/tests/tcg/hello-arm.c b/tests/tcg/hello-arm.c new file mode 100644 index 00000000..e0daa7ad --- /dev/null +++ b/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/tests/tcg/hello-i386.c b/tests/tcg/hello-i386.c new file mode 100644 index 00000000..fa00380d --- /dev/null +++ b/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/tests/tcg/hello-mips.c b/tests/tcg/hello-mips.c new file mode 100644 index 00000000..f8256730 --- /dev/null +++ b/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/tests/tcg/linux-test.c b/tests/tcg/linux-test.c new file mode 100644 index 00000000..1c6c0131 --- /dev/null +++ b/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/tests/tcg/lm32/Makefile b/tests/tcg/lm32/Makefile new file mode 100644 index 00000000..57e7363b --- /dev/null +++ b/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/tests/tcg/lm32/crt.S b/tests/tcg/lm32/crt.S new file mode 100644 index 00000000..fc437a3d --- /dev/null +++ b/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/tests/tcg/lm32/helper.S b/tests/tcg/lm32/helper.S new file mode 100644 index 00000000..3351d41e --- /dev/null +++ b/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/tests/tcg/lm32/linker.ld b/tests/tcg/lm32/linker.ld new file mode 100644 index 00000000..52d43a4c --- /dev/null +++ b/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/tests/tcg/lm32/macros.inc b/tests/tcg/lm32/macros.inc new file mode 100644 index 00000000..360ad53c --- /dev/null +++ b/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/tests/tcg/lm32/test_add.S b/tests/tcg/lm32/test_add.S new file mode 100644 index 00000000..030ad197 --- /dev/null +++ b/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/tests/tcg/lm32/test_addi.S b/tests/tcg/lm32/test_addi.S new file mode 100644 index 00000000..68e766d1 --- /dev/null +++ b/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/tests/tcg/lm32/test_and.S b/tests/tcg/lm32/test_and.S new file mode 100644 index 00000000..80962ce7 --- /dev/null +++ b/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/tests/tcg/lm32/test_andhi.S b/tests/tcg/lm32/test_andhi.S new file mode 100644 index 00000000..4f73af55 --- /dev/null +++ b/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/tests/tcg/lm32/test_andi.S b/tests/tcg/lm32/test_andi.S new file mode 100644 index 00000000..da1b0a32 --- /dev/null +++ b/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/tests/tcg/lm32/test_b.S b/tests/tcg/lm32/test_b.S new file mode 100644 index 00000000..98172d8a --- /dev/null +++ b/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/tests/tcg/lm32/test_be.S b/tests/tcg/lm32/test_be.S new file mode 100644 index 00000000..635cabac --- /dev/null +++ b/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/tests/tcg/lm32/test_bg.S b/tests/tcg/lm32/test_bg.S new file mode 100644 index 00000000..81823c23 --- /dev/null +++ b/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/tests/tcg/lm32/test_bge.S b/tests/tcg/lm32/test_bge.S new file mode 100644 index 00000000..6684d15a --- /dev/null +++ b/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/tests/tcg/lm32/test_bgeu.S b/tests/tcg/lm32/test_bgeu.S new file mode 100644 index 00000000..be440308 --- /dev/null +++ b/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/tests/tcg/lm32/test_bgu.S b/tests/tcg/lm32/test_bgu.S new file mode 100644 index 00000000..8cc695b3 --- /dev/null +++ b/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/tests/tcg/lm32/test_bi.S b/tests/tcg/lm32/test_bi.S new file mode 100644 index 00000000..a1fbd6fc --- /dev/null +++ b/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/tests/tcg/lm32/test_bne.S b/tests/tcg/lm32/test_bne.S new file mode 100644 index 00000000..871a0067 --- /dev/null +++ b/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/tests/tcg/lm32/test_break.S b/tests/tcg/lm32/test_break.S new file mode 100644 index 00000000..0384fc61 --- /dev/null +++ b/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/tests/tcg/lm32/test_bret.S b/tests/tcg/lm32/test_bret.S new file mode 100644 index 00000000..645210e4 --- /dev/null +++ b/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/tests/tcg/lm32/test_call.S b/tests/tcg/lm32/test_call.S new file mode 100644 index 00000000..1b91a5f2 --- /dev/null +++ b/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/tests/tcg/lm32/test_calli.S b/tests/tcg/lm32/test_calli.S new file mode 100644 index 00000000..1d87ae6e --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpe.S b/tests/tcg/lm32/test_cmpe.S new file mode 100644 index 00000000..60a88550 --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpei.S b/tests/tcg/lm32/test_cmpei.S new file mode 100644 index 00000000..c3d3566a --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpg.S b/tests/tcg/lm32/test_cmpg.S new file mode 100644 index 00000000..01240787 --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpge.S b/tests/tcg/lm32/test_cmpge.S new file mode 100644 index 00000000..84620a00 --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpgei.S b/tests/tcg/lm32/test_cmpgei.S new file mode 100644 index 00000000..6e388a2a --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpgeu.S b/tests/tcg/lm32/test_cmpgeu.S new file mode 100644 index 00000000..2110ccb6 --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpgeui.S b/tests/tcg/lm32/test_cmpgeui.S new file mode 100644 index 00000000..3866d96c --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpgi.S b/tests/tcg/lm32/test_cmpgi.S new file mode 100644 index 00000000..21695f97 --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpgu.S b/tests/tcg/lm32/test_cmpgu.S new file mode 100644 index 00000000..dd465471 --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpgui.S b/tests/tcg/lm32/test_cmpgui.S new file mode 100644 index 00000000..dd940014 --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpne.S b/tests/tcg/lm32/test_cmpne.S new file mode 100644 index 00000000..0f107811 --- /dev/null +++ b/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/tests/tcg/lm32/test_cmpnei.S b/tests/tcg/lm32/test_cmpnei.S new file mode 100644 index 00000000..060dd9d3 --- /dev/null +++ b/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/tests/tcg/lm32/test_divu.S b/tests/tcg/lm32/test_divu.S new file mode 100644 index 00000000..f381d095 --- /dev/null +++ b/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/tests/tcg/lm32/test_eret.S b/tests/tcg/lm32/test_eret.S new file mode 100644 index 00000000..6830bd1a --- /dev/null +++ b/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/tests/tcg/lm32/test_lb.S b/tests/tcg/lm32/test_lb.S new file mode 100644 index 00000000..d677eea4 --- /dev/null +++ b/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/tests/tcg/lm32/test_lbu.S b/tests/tcg/lm32/test_lbu.S new file mode 100644 index 00000000..dc5d5f67 --- /dev/null +++ b/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/tests/tcg/lm32/test_lh.S b/tests/tcg/lm32/test_lh.S new file mode 100644 index 00000000..397996bd --- /dev/null +++ b/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/tests/tcg/lm32/test_lhu.S b/tests/tcg/lm32/test_lhu.S new file mode 100644 index 00000000..8de7c525 --- /dev/null +++ b/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/tests/tcg/lm32/test_lw.S b/tests/tcg/lm32/test_lw.S new file mode 100644 index 00000000..996e5f8c --- /dev/null +++ b/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/tests/tcg/lm32/test_modu.S b/tests/tcg/lm32/test_modu.S new file mode 100644 index 00000000..42486900 --- /dev/null +++ b/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/tests/tcg/lm32/test_mul.S b/tests/tcg/lm32/test_mul.S new file mode 100644 index 00000000..e9b937e6 --- /dev/null +++ b/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/tests/tcg/lm32/test_muli.S b/tests/tcg/lm32/test_muli.S new file mode 100644 index 00000000..d6dd4a0f --- /dev/null +++ b/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/tests/tcg/lm32/test_nor.S b/tests/tcg/lm32/test_nor.S new file mode 100644 index 00000000..74d75925 --- /dev/null +++ b/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/tests/tcg/lm32/test_nori.S b/tests/tcg/lm32/test_nori.S new file mode 100644 index 00000000..d00309c7 --- /dev/null +++ b/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/tests/tcg/lm32/test_or.S b/tests/tcg/lm32/test_or.S new file mode 100644 index 00000000..4ed29233 --- /dev/null +++ b/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/tests/tcg/lm32/test_orhi.S b/tests/tcg/lm32/test_orhi.S new file mode 100644 index 00000000..78b7600e --- /dev/null +++ b/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/tests/tcg/lm32/test_ori.S b/tests/tcg/lm32/test_ori.S new file mode 100644 index 00000000..3d576cdb --- /dev/null +++ b/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/tests/tcg/lm32/test_ret.S b/tests/tcg/lm32/test_ret.S new file mode 100644 index 00000000..320264f1 --- /dev/null +++ b/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/tests/tcg/lm32/test_sb.S b/tests/tcg/lm32/test_sb.S new file mode 100644 index 00000000..b15a89d3 --- /dev/null +++ b/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/tests/tcg/lm32/test_scall.S b/tests/tcg/lm32/test_scall.S new file mode 100644 index 00000000..46032f84 --- /dev/null +++ b/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/tests/tcg/lm32/test_sextb.S b/tests/tcg/lm32/test_sextb.S new file mode 100644 index 00000000..58db8ee8 --- /dev/null +++ b/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/tests/tcg/lm32/test_sexth.S b/tests/tcg/lm32/test_sexth.S new file mode 100644 index 00000000..a059ec3e --- /dev/null +++ b/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/tests/tcg/lm32/test_sh.S b/tests/tcg/lm32/test_sh.S new file mode 100644 index 00000000..bba10224 --- /dev/null +++ b/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/tests/tcg/lm32/test_sl.S b/tests/tcg/lm32/test_sl.S new file mode 100644 index 00000000..0aee17fd --- /dev/null +++ b/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/tests/tcg/lm32/test_sli.S b/tests/tcg/lm32/test_sli.S new file mode 100644 index 00000000..a421de90 --- /dev/null +++ b/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/tests/tcg/lm32/test_sr.S b/tests/tcg/lm32/test_sr.S new file mode 100644 index 00000000..62431a98 --- /dev/null +++ b/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/tests/tcg/lm32/test_sri.S b/tests/tcg/lm32/test_sri.S new file mode 100644 index 00000000..c1be907b --- /dev/null +++ b/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/tests/tcg/lm32/test_sru.S b/tests/tcg/lm32/test_sru.S new file mode 100644 index 00000000..2ab0b54c --- /dev/null +++ b/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/tests/tcg/lm32/test_srui.S b/tests/tcg/lm32/test_srui.S new file mode 100644 index 00000000..872c3741 --- /dev/null +++ b/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/tests/tcg/lm32/test_sub.S b/tests/tcg/lm32/test_sub.S new file mode 100644 index 00000000..44b74a9e --- /dev/null +++ b/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/tests/tcg/lm32/test_sw.S b/tests/tcg/lm32/test_sw.S new file mode 100644 index 00000000..2b1c017e --- /dev/null +++ b/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/tests/tcg/lm32/test_xnor.S b/tests/tcg/lm32/test_xnor.S new file mode 100644 index 00000000..14a62075 --- /dev/null +++ b/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/tests/tcg/lm32/test_xnori.S b/tests/tcg/lm32/test_xnori.S new file mode 100644 index 00000000..9d9c3c67 --- /dev/null +++ b/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/tests/tcg/lm32/test_xor.S b/tests/tcg/lm32/test_xor.S new file mode 100644 index 00000000..6c6e712b --- /dev/null +++ b/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/tests/tcg/lm32/test_xori.S b/tests/tcg/lm32/test_xori.S new file mode 100644 index 00000000..2051699f --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/Makefile b/tests/tcg/mips/mips32-dsp/Makefile new file mode 100644 index 00000000..c3a0a009 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/absq_s_ph.c b/tests/tcg/mips/mips32-dsp/absq_s_ph.c new file mode 100644 index 00000000..aa841120 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/absq_s_w.c b/tests/tcg/mips/mips32-dsp/absq_s_w.c new file mode 100644 index 00000000..3f52a480 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/addq_ph.c b/tests/tcg/mips/mips32-dsp/addq_ph.c new file mode 100644 index 00000000..96a54963 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/addq_s_ph.c b/tests/tcg/mips/mips32-dsp/addq_s_ph.c new file mode 100644 index 00000000..5f865f6c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/addq_s_w.c b/tests/tcg/mips/mips32-dsp/addq_s_w.c new file mode 100644 index 00000000..1e13acf6 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/addsc.c b/tests/tcg/mips/mips32-dsp/addsc.c new file mode 100644 index 00000000..ace749f6 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/addu_qb.c b/tests/tcg/mips/mips32-dsp/addu_qb.c new file mode 100644 index 00000000..23ba2e90 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/addu_s_qb.c b/tests/tcg/mips/mips32-dsp/addu_s_qb.c new file mode 100644 index 00000000..fe7fd3e6 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/addwc.c b/tests/tcg/mips/mips32-dsp/addwc.c new file mode 100644 index 00000000..8a8d81fa --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/bitrev.c b/tests/tcg/mips/mips32-dsp/bitrev.c new file mode 100644 index 00000000..04d8a384 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/bposge32.c b/tests/tcg/mips/mips32-dsp/bposge32.c new file mode 100644 index 00000000..d25417ea --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c b/tests/tcg/mips/mips32-dsp/cmp_eq_ph.c new file mode 100644 index 00000000..957bd88c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/cmp_le_ph.c b/tests/tcg/mips/mips32-dsp/cmp_le_ph.c new file mode 100644 index 00000000..356f156c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c b/tests/tcg/mips/mips32-dsp/cmp_lt_ph.c new file mode 100644 index 00000000..3fb4827a --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c b/tests/tcg/mips/mips32-dsp/cmpgu_eq_qb.c new file mode 100644 index 00000000..2615c84c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c b/tests/tcg/mips/mips32-dsp/cmpgu_le_qb.c new file mode 100644 index 00000000..65d0813c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c b/tests/tcg/mips/mips32-dsp/cmpgu_lt_qb.c new file mode 100644 index 00000000..7dddad98 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c b/tests/tcg/mips/mips32-dsp/cmpu_eq_qb.c new file mode 100644 index 00000000..680f2a19 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c b/tests/tcg/mips/mips32-dsp/cmpu_le_qb.c new file mode 100644 index 00000000..43cfa509 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c b/tests/tcg/mips/mips32-dsp/cmpu_lt_qb.c new file mode 100644 index 00000000..074ca5b4 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c b/tests/tcg/mips/mips32-dsp/dpaq_s_w_ph.c new file mode 100644 index 00000000..a6425b6e --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c b/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c new file mode 100644 index 00000000..cbf90071 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c b/tests/tcg/mips/mips32-dsp/dpau_h_qbl.c new file mode 100644 index 00000000..6017b5e7 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c b/tests/tcg/mips/mips32-dsp/dpau_h_qbr.c new file mode 100644 index 00000000..e4abb2e2 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c b/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c new file mode 100644 index 00000000..74058fe7 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c b/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c new file mode 100644 index 00000000..eda3b14e --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c b/tests/tcg/mips/mips32-dsp/dpsu_h_qbl.c new file mode 100644 index 00000000..94e2bf62 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c b/tests/tcg/mips/mips32-dsp/dpsu_h_qbr.c new file mode 100644 index 00000000..a1e66356 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extp.c b/tests/tcg/mips/mips32-dsp/extp.c new file mode 100644 index 00000000..b18bdb34 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extpdp.c b/tests/tcg/mips/mips32-dsp/extpdp.c new file mode 100644 index 00000000..79ee16e8 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extpdpv.c b/tests/tcg/mips/mips32-dsp/extpdpv.c new file mode 100644 index 00000000..f5774eed --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extpv.c b/tests/tcg/mips/mips32-dsp/extpv.c new file mode 100644 index 00000000..401b94af --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extr_r_w.c b/tests/tcg/mips/mips32-dsp/extr_r_w.c new file mode 100644 index 00000000..489c1931 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extr_rs_w.c b/tests/tcg/mips/mips32-dsp/extr_rs_w.c new file mode 100644 index 00000000..f9d2ed64 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extr_s_h.c b/tests/tcg/mips/mips32-dsp/extr_s_h.c new file mode 100644 index 00000000..9bc2a63c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extr_w.c b/tests/tcg/mips/mips32-dsp/extr_w.c new file mode 100644 index 00000000..cf926146 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extrv_r_w.c b/tests/tcg/mips/mips32-dsp/extrv_r_w.c new file mode 100644 index 00000000..2403b3af --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extrv_rs_w.c b/tests/tcg/mips/mips32-dsp/extrv_rs_w.c new file mode 100644 index 00000000..ccceeb9f --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extrv_s_h.c b/tests/tcg/mips/mips32-dsp/extrv_s_h.c new file mode 100644 index 00000000..feac3e2e --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/extrv_w.c b/tests/tcg/mips/mips32-dsp/extrv_w.c new file mode 100644 index 00000000..9e8b238a --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/insv.c b/tests/tcg/mips/mips32-dsp/insv.c new file mode 100644 index 00000000..9d674697 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/lbux.c b/tests/tcg/mips/mips32-dsp/lbux.c new file mode 100644 index 00000000..2337abea --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/lhx.c b/tests/tcg/mips/mips32-dsp/lhx.c new file mode 100644 index 00000000..10be3b38 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/lwx.c b/tests/tcg/mips/mips32-dsp/lwx.c new file mode 100644 index 00000000..e6543c9e --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/madd.c b/tests/tcg/mips/mips32-dsp/madd.c new file mode 100644 index 00000000..af4bfcfe --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/maddu.c b/tests/tcg/mips/mips32-dsp/maddu.c new file mode 100644 index 00000000..af4bfcfe --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/main.c b/tests/tcg/mips/mips32-dsp/main.c new file mode 100644 index 00000000..b296b20c --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/main.c @@ -0,0 +1,6 @@ +#include<stdio.h> + +int main() +{ +    printf("hello world\n"); +} diff --git a/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c b/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c new file mode 100644 index 00000000..0f7c0701 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c b/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c new file mode 100644 index 00000000..942722a5 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c b/tests/tcg/mips/mips32-dsp/maq_sa_w_phl.c new file mode 100644 index 00000000..d83dce6f --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c b/tests/tcg/mips/mips32-dsp/maq_sa_w_phr.c new file mode 100644 index 00000000..d2331118 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/mfhi.c b/tests/tcg/mips/mips32-dsp/mfhi.c new file mode 100644 index 00000000..43a80669 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/mflo.c b/tests/tcg/mips/mips32-dsp/mflo.c new file mode 100644 index 00000000..caeafdb0 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/modsub.c b/tests/tcg/mips/mips32-dsp/modsub.c new file mode 100644 index 00000000..c294eebb --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/msub.c b/tests/tcg/mips/mips32-dsp/msub.c new file mode 100644 index 00000000..5779e6f4 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/msubu.c b/tests/tcg/mips/mips32-dsp/msubu.c new file mode 100644 index 00000000..e0f9b5a7 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/mthi.c b/tests/tcg/mips/mips32-dsp/mthi.c new file mode 100644 index 00000000..43a80669 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/mthlip.c b/tests/tcg/mips/mips32-dsp/mthlip.c new file mode 100644 index 00000000..85f94d84 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/mtlo.c b/tests/tcg/mips/mips32-dsp/mtlo.c new file mode 100644 index 00000000..caeafdb0 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/muleq_s_w_phl.c b/tests/tcg/mips/mips32-dsp/muleq_s_w_phl.c new file mode 100644 index 00000000..b3a5370f --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c b/tests/tcg/mips/mips32-dsp/muleq_s_w_phr.c new file mode 100644 index 00000000..8066d7d0 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c b/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbl.c new file mode 100644 index 00000000..66a38280 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c b/tests/tcg/mips/mips32-dsp/muleu_s_ph_qbr.c new file mode 100644 index 00000000..4cc6c8f7 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c b/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c new file mode 100644 index 00000000..370c2a80 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/mult.c b/tests/tcg/mips/mips32-dsp/mult.c new file mode 100644 index 00000000..15e6fde9 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/multu.c b/tests/tcg/mips/mips32-dsp/multu.c new file mode 100644 index 00000000..85d36c1b --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/packrl_ph.c b/tests/tcg/mips/mips32-dsp/packrl_ph.c new file mode 100644 index 00000000..1f8e6999 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/pick_ph.c b/tests/tcg/mips/mips32-dsp/pick_ph.c new file mode 100644 index 00000000..929a002e --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/pick_qb.c b/tests/tcg/mips/mips32-dsp/pick_qb.c new file mode 100644 index 00000000..a7904752 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/preceq_w_phl.c b/tests/tcg/mips/mips32-dsp/preceq_w_phl.c new file mode 100644 index 00000000..bf70bf7d --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/preceq_w_phr.c b/tests/tcg/mips/mips32-dsp/preceq_w_phr.c new file mode 100644 index 00000000..3f885ef5 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c b/tests/tcg/mips/mips32-dsp/precequ_ph_qbl.c new file mode 100644 index 00000000..63b7a956 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c b/tests/tcg/mips/mips32-dsp/precequ_ph_qbla.c new file mode 100644 index 00000000..31627f0b --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c b/tests/tcg/mips/mips32-dsp/precequ_ph_qbr.c new file mode 100644 index 00000000..b6f72d3c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c b/tests/tcg/mips/mips32-dsp/precequ_ph_qbra.c new file mode 100644 index 00000000..4764fd03 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c b/tests/tcg/mips/mips32-dsp/preceu_ph_qbl.c new file mode 100644 index 00000000..fa95c26c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c b/tests/tcg/mips/mips32-dsp/preceu_ph_qbla.c new file mode 100644 index 00000000..021f21a7 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c b/tests/tcg/mips/mips32-dsp/preceu_ph_qbr.c new file mode 100644 index 00000000..03df18c7 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c b/tests/tcg/mips/mips32-dsp/preceu_ph_qbra.c new file mode 100644 index 00000000..63432761 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/precrq_ph_w.c b/tests/tcg/mips/mips32-dsp/precrq_ph_w.c new file mode 100644 index 00000000..25d45f1a --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c b/tests/tcg/mips/mips32-dsp/precrq_qb_ph.c new file mode 100644 index 00000000..fe23acce --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c b/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c new file mode 100644 index 00000000..da6845bf --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c b/tests/tcg/mips/mips32-dsp/precrqu_s_qb_ph.c new file mode 100644 index 00000000..7481d5af --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/raddu_w_qb.c b/tests/tcg/mips/mips32-dsp/raddu_w_qb.c new file mode 100644 index 00000000..77a983c0 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/rddsp.c b/tests/tcg/mips/mips32-dsp/rddsp.c new file mode 100644 index 00000000..2f302850 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/repl_ph.c b/tests/tcg/mips/mips32-dsp/repl_ph.c new file mode 100644 index 00000000..21074953 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/repl_qb.c b/tests/tcg/mips/mips32-dsp/repl_qb.c new file mode 100644 index 00000000..6631393e --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/replv_ph.c b/tests/tcg/mips/mips32-dsp/replv_ph.c new file mode 100644 index 00000000..07fb15f1 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/replv_qb.c b/tests/tcg/mips/mips32-dsp/replv_qb.c new file mode 100644 index 00000000..dd1271fe --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shilo.c b/tests/tcg/mips/mips32-dsp/shilo.c new file mode 100644 index 00000000..ce8ebc69 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shilov.c b/tests/tcg/mips/mips32-dsp/shilov.c new file mode 100644 index 00000000..e1d6cea4 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shll_ph.c b/tests/tcg/mips/mips32-dsp/shll_ph.c new file mode 100644 index 00000000..5fa58ccf --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shll_qb.c b/tests/tcg/mips/mips32-dsp/shll_qb.c new file mode 100644 index 00000000..729716d6 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shll_s_ph.c b/tests/tcg/mips/mips32-dsp/shll_s_ph.c new file mode 100644 index 00000000..910fea3b --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shll_s_w.c b/tests/tcg/mips/mips32-dsp/shll_s_w.c new file mode 100644 index 00000000..628c7521 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shllv_ph.c b/tests/tcg/mips/mips32-dsp/shllv_ph.c new file mode 100644 index 00000000..f98a6322 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shllv_qb.c b/tests/tcg/mips/mips32-dsp/shllv_qb.c new file mode 100644 index 00000000..6d8ff4a2 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shllv_s_ph.c b/tests/tcg/mips/mips32-dsp/shllv_s_ph.c new file mode 100644 index 00000000..fc9bd327 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shllv_s_w.c b/tests/tcg/mips/mips32-dsp/shllv_s_w.c new file mode 100644 index 00000000..350c2561 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shra_ph.c b/tests/tcg/mips/mips32-dsp/shra_ph.c new file mode 100644 index 00000000..5b2d840a --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shra_r_ph.c b/tests/tcg/mips/mips32-dsp/shra_r_ph.c new file mode 100644 index 00000000..adc4ae68 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shra_r_w.c b/tests/tcg/mips/mips32-dsp/shra_r_w.c new file mode 100644 index 00000000..ec0cf2c7 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shrav_ph.c b/tests/tcg/mips/mips32-dsp/shrav_ph.c new file mode 100644 index 00000000..6e42aaf8 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shrav_r_ph.c b/tests/tcg/mips/mips32-dsp/shrav_r_ph.c new file mode 100644 index 00000000..f03b978d --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shrav_r_w.c b/tests/tcg/mips/mips32-dsp/shrav_r_w.c new file mode 100644 index 00000000..2ab03bb5 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shrl_qb.c b/tests/tcg/mips/mips32-dsp/shrl_qb.c new file mode 100644 index 00000000..a7e4e6a5 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/shrlv_qb.c b/tests/tcg/mips/mips32-dsp/shrlv_qb.c new file mode 100644 index 00000000..db77f6d0 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/subq_ph.c b/tests/tcg/mips/mips32-dsp/subq_ph.c new file mode 100644 index 00000000..fdd7b38b --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/subq_s_ph.c b/tests/tcg/mips/mips32-dsp/subq_s_ph.c new file mode 100644 index 00000000..64c89ebd --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/subq_s_w.c b/tests/tcg/mips/mips32-dsp/subq_s_w.c new file mode 100644 index 00000000..9d456a90 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/subu_qb.c b/tests/tcg/mips/mips32-dsp/subu_qb.c new file mode 100644 index 00000000..42090961 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/subu_s_qb.c b/tests/tcg/mips/mips32-dsp/subu_s_qb.c new file mode 100644 index 00000000..3d650533 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dsp/wrdsp.c b/tests/tcg/mips/mips32-dsp/wrdsp.c new file mode 100644 index 00000000..dc54943a --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/Makefile b/tests/tcg/mips/mips32-dspr2/Makefile new file mode 100644 index 00000000..ed19581c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/absq_s_qb.c b/tests/tcg/mips/mips32-dspr2/absq_s_qb.c new file mode 100644 index 00000000..af4683f3 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/addqh_ph.c b/tests/tcg/mips/mips32-dspr2/addqh_ph.c new file mode 100644 index 00000000..921f0eaf --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/addqh_r_ph.c b/tests/tcg/mips/mips32-dspr2/addqh_r_ph.c new file mode 100644 index 00000000..213ba372 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/addqh_r_w.c b/tests/tcg/mips/mips32-dspr2/addqh_r_w.c new file mode 100644 index 00000000..75a75c50 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/addqh_w.c b/tests/tcg/mips/mips32-dspr2/addqh_w.c new file mode 100644 index 00000000..de6926eb --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/addu_ph.c b/tests/tcg/mips/mips32-dspr2/addu_ph.c new file mode 100644 index 00000000..1d7a25a2 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/addu_s_ph.c b/tests/tcg/mips/mips32-dspr2/addu_s_ph.c new file mode 100644 index 00000000..979651bf --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/adduh_qb.c b/tests/tcg/mips/mips32-dspr2/adduh_qb.c new file mode 100644 index 00000000..a1f5d631 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/adduh_r_qb.c b/tests/tcg/mips/mips32-dspr2/adduh_r_qb.c new file mode 100644 index 00000000..81e98c19 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/append.c b/tests/tcg/mips/mips32-dspr2/append.c new file mode 100644 index 00000000..9a91e165 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/balign.c b/tests/tcg/mips/mips32-dspr2/balign.c new file mode 100644 index 00000000..537cf045 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c b/tests/tcg/mips/mips32-dspr2/cmpgdu_eq_qb.c new file mode 100644 index 00000000..2d6340d6 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c b/tests/tcg/mips/mips32-dspr2/cmpgdu_le_qb.c new file mode 100644 index 00000000..a0ecdca2 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c b/tests/tcg/mips/mips32-dspr2/cmpgdu_lt_qb.c new file mode 100644 index 00000000..dba99e39 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/dpa_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpa_w_ph.c new file mode 100644 index 00000000..fae49f10 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpaqx_s_w_ph.c new file mode 100644 index 00000000..ce878302 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c new file mode 100644 index 00000000..d551d64a --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/dpax_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpax_w_ph.c new file mode 100644 index 00000000..514797cf --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/dps_w_ph.c b/tests/tcg/mips/mips32-dspr2/dps_w_ph.c new file mode 100644 index 00000000..f51f9b9d --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c new file mode 100644 index 00000000..e40543fd --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpsqx_sa_w_ph.c new file mode 100644 index 00000000..7da278ea --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpsx_w_ph.c new file mode 100644 index 00000000..bb49a403 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/mul_ph.c b/tests/tcg/mips/mips32-dspr2/mul_ph.c new file mode 100644 index 00000000..c7e9d60d --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/mul_s_ph.c b/tests/tcg/mips/mips32-dspr2/mul_s_ph.c new file mode 100644 index 00000000..33da110d --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/mulq_rs_w.c b/tests/tcg/mips/mips32-dspr2/mulq_rs_w.c new file mode 100644 index 00000000..7ba633bc --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/mulq_s_ph.c b/tests/tcg/mips/mips32-dspr2/mulq_s_ph.c new file mode 100644 index 00000000..00e01554 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/mulq_s_w.c b/tests/tcg/mips/mips32-dspr2/mulq_s_w.c new file mode 100644 index 00000000..9c2be06c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c b/tests/tcg/mips/mips32-dspr2/mulsa_w_ph.c new file mode 100644 index 00000000..a6940939 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c b/tests/tcg/mips/mips32-dspr2/mulsaq_s_w_ph.c new file mode 100644 index 00000000..06c91a43 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/precr_qb_ph.c b/tests/tcg/mips/mips32-dspr2/precr_qb_ph.c new file mode 100644 index 00000000..3a2b3fde --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c b/tests/tcg/mips/mips32-dspr2/precr_sra_ph_w.c new file mode 100644 index 00000000..5c9baab0 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c b/tests/tcg/mips/mips32-dspr2/precr_sra_r_ph_w.c new file mode 100644 index 00000000..6474a108 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/prepend.c b/tests/tcg/mips/mips32-dspr2/prepend.c new file mode 100644 index 00000000..f6bcd47b --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/shra_qb.c b/tests/tcg/mips/mips32-dspr2/shra_qb.c new file mode 100644 index 00000000..48193de8 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/shra_r_qb.c b/tests/tcg/mips/mips32-dspr2/shra_r_qb.c new file mode 100644 index 00000000..29afa0e4 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/shrav_qb.c b/tests/tcg/mips/mips32-dspr2/shrav_qb.c new file mode 100644 index 00000000..b21e1b7c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/shrav_r_qb.c b/tests/tcg/mips/mips32-dspr2/shrav_r_qb.c new file mode 100644 index 00000000..9ea8aa0c --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/shrl_ph.c b/tests/tcg/mips/mips32-dspr2/shrl_ph.c new file mode 100644 index 00000000..724b9a7a --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/shrlv_ph.c b/tests/tcg/mips/mips32-dspr2/shrlv_ph.c new file mode 100644 index 00000000..ac79aa69 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/subqh_ph.c b/tests/tcg/mips/mips32-dspr2/subqh_ph.c new file mode 100644 index 00000000..dbc09673 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/subqh_r_ph.c b/tests/tcg/mips/mips32-dspr2/subqh_r_ph.c new file mode 100644 index 00000000..24ef0f1a --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/subqh_r_w.c b/tests/tcg/mips/mips32-dspr2/subqh_r_w.c new file mode 100644 index 00000000..d460f863 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/subqh_w.c b/tests/tcg/mips/mips32-dspr2/subqh_w.c new file mode 100644 index 00000000..42be3deb --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/subu_ph.c b/tests/tcg/mips/mips32-dspr2/subu_ph.c new file mode 100644 index 00000000..0d39a017 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/subu_s_ph.c b/tests/tcg/mips/mips32-dspr2/subu_s_ph.c new file mode 100644 index 00000000..8e4da4f3 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/subuh_qb.c b/tests/tcg/mips/mips32-dspr2/subuh_qb.c new file mode 100644 index 00000000..92cfc764 --- /dev/null +++ b/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/tests/tcg/mips/mips32-dspr2/subuh_r_qb.c b/tests/tcg/mips/mips32-dspr2/subuh_r_qb.c new file mode 100644 index 00000000..dac81d47 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/Makefile b/tests/tcg/mips/mips64-dsp/Makefile new file mode 100644 index 00000000..b2ac6b3f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/absq_s_ob.c b/tests/tcg/mips/mips64-dsp/absq_s_ob.c new file mode 100644 index 00000000..62140315 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/absq_s_ph.c b/tests/tcg/mips/mips64-dsp/absq_s_ph.c new file mode 100644 index 00000000..238416d4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/absq_s_pw.c b/tests/tcg/mips/mips64-dsp/absq_s_pw.c new file mode 100644 index 00000000..48fc763b --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/absq_s_qh.c b/tests/tcg/mips/mips64-dsp/absq_s_qh.c new file mode 100644 index 00000000..9001a9e1 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/absq_s_w.c b/tests/tcg/mips/mips64-dsp/absq_s_w.c new file mode 100644 index 00000000..414c8bd3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addq_ph.c b/tests/tcg/mips/mips64-dsp/addq_ph.c new file mode 100644 index 00000000..22a36d98 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addq_pw.c b/tests/tcg/mips/mips64-dsp/addq_pw.c new file mode 100644 index 00000000..99a7668c --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addq_qh.c b/tests/tcg/mips/mips64-dsp/addq_qh.c new file mode 100644 index 00000000..4b874afb --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addq_s_ph.c b/tests/tcg/mips/mips64-dsp/addq_s_ph.c new file mode 100644 index 00000000..ad84cdcf --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addq_s_pw.c b/tests/tcg/mips/mips64-dsp/addq_s_pw.c new file mode 100644 index 00000000..2e380bbf --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addq_s_qh.c b/tests/tcg/mips/mips64-dsp/addq_s_qh.c new file mode 100644 index 00000000..b638a2b9 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addq_s_w.c b/tests/tcg/mips/mips64-dsp/addq_s_w.c new file mode 100644 index 00000000..3e08f5d4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addsc.c b/tests/tcg/mips/mips64-dsp/addsc.c new file mode 100644 index 00000000..4b684b9b --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addu_ob.c b/tests/tcg/mips/mips64-dsp/addu_ob.c new file mode 100644 index 00000000..17f9c668 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addu_qb.c b/tests/tcg/mips/mips64-dsp/addu_qb.c new file mode 100644 index 00000000..3b9b5fc5 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addu_s_ob.c b/tests/tcg/mips/mips64-dsp/addu_s_ob.c new file mode 100644 index 00000000..e89a4638 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addu_s_qb.c b/tests/tcg/mips/mips64-dsp/addu_s_qb.c new file mode 100644 index 00000000..cb84293a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/addwc.c b/tests/tcg/mips/mips64-dsp/addwc.c new file mode 100644 index 00000000..5929cd2f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/bitrev.c b/tests/tcg/mips/mips64-dsp/bitrev.c new file mode 100644 index 00000000..ac24ef3f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/bposge32.c b/tests/tcg/mips/mips64-dsp/bposge32.c new file mode 100644 index 00000000..97bce446 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/bposge64.c b/tests/tcg/mips/mips64-dsp/bposge64.c new file mode 100644 index 00000000..36161ad8 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmp_eq_ph.c b/tests/tcg/mips/mips64-dsp/cmp_eq_ph.c new file mode 100644 index 00000000..63069d0d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmp_eq_pw.c b/tests/tcg/mips/mips64-dsp/cmp_eq_pw.c new file mode 100644 index 00000000..bae4c06c --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmp_eq_qh.c b/tests/tcg/mips/mips64-dsp/cmp_eq_qh.c new file mode 100644 index 00000000..49ea2710 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmp_le_ph.c b/tests/tcg/mips/mips64-dsp/cmp_le_ph.c new file mode 100644 index 00000000..12d24f17 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmp_le_pw.c b/tests/tcg/mips/mips64-dsp/cmp_le_pw.c new file mode 100644 index 00000000..6acc43cd --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmp_le_qh.c b/tests/tcg/mips/mips64-dsp/cmp_le_qh.c new file mode 100644 index 00000000..c9ce2166 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmp_lt_ph.c b/tests/tcg/mips/mips64-dsp/cmp_lt_ph.c new file mode 100644 index 00000000..1d91228c --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmp_lt_pw.c b/tests/tcg/mips/mips64-dsp/cmp_lt_pw.c new file mode 100644 index 00000000..87e74caf --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmp_lt_qh.c b/tests/tcg/mips/mips64-dsp/cmp_lt_qh.c new file mode 100644 index 00000000..0a13a5ea --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpgu_eq_ob.c b/tests/tcg/mips/mips64-dsp/cmpgu_eq_ob.c new file mode 100644 index 00000000..697d73dd --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpgu_eq_qb.c b/tests/tcg/mips/mips64-dsp/cmpgu_eq_qb.c new file mode 100644 index 00000000..b41c4430 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpgu_le_ob.c b/tests/tcg/mips/mips64-dsp/cmpgu_le_ob.c new file mode 100644 index 00000000..8b65f18c --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpgu_le_qb.c b/tests/tcg/mips/mips64-dsp/cmpgu_le_qb.c new file mode 100644 index 00000000..dd2b091f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpgu_lt_ob.c b/tests/tcg/mips/mips64-dsp/cmpgu_lt_ob.c new file mode 100644 index 00000000..3e5c9dd6 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpgu_lt_qb.c b/tests/tcg/mips/mips64-dsp/cmpgu_lt_qb.c new file mode 100644 index 00000000..a467cb78 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpu_eq_ob.c b/tests/tcg/mips/mips64-dsp/cmpu_eq_ob.c new file mode 100644 index 00000000..4d1983e5 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpu_eq_qb.c b/tests/tcg/mips/mips64-dsp/cmpu_eq_qb.c new file mode 100644 index 00000000..28f3bec2 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpu_le_ob.c b/tests/tcg/mips/mips64-dsp/cmpu_le_ob.c new file mode 100644 index 00000000..8acbd1c4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpu_le_qb.c b/tests/tcg/mips/mips64-dsp/cmpu_le_qb.c new file mode 100644 index 00000000..8a17a085 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpu_lt_ob.c b/tests/tcg/mips/mips64-dsp/cmpu_lt_ob.c new file mode 100644 index 00000000..34e312d8 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/cmpu_lt_qb.c b/tests/tcg/mips/mips64-dsp/cmpu_lt_qb.c new file mode 100644 index 00000000..adb75eed --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dappend.c b/tests/tcg/mips/mips64-dsp/dappend.c new file mode 100644 index 00000000..ba8e1218 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextp.c b/tests/tcg/mips/mips64-dsp/dextp.c new file mode 100644 index 00000000..a469cc03 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextpdp.c b/tests/tcg/mips/mips64-dsp/dextpdp.c new file mode 100644 index 00000000..a2361e2d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextpdpv.c b/tests/tcg/mips/mips64-dsp/dextpdpv.c new file mode 100644 index 00000000..09c0b5b4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextpv.c b/tests/tcg/mips/mips64-dsp/dextpv.c new file mode 100644 index 00000000..2626f3d9 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextr_l.c b/tests/tcg/mips/mips64-dsp/dextr_l.c new file mode 100644 index 00000000..538846df --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextr_r_l.c b/tests/tcg/mips/mips64-dsp/dextr_r_l.c new file mode 100644 index 00000000..a10a9ab4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextr_r_w.c b/tests/tcg/mips/mips64-dsp/dextr_r_w.c new file mode 100644 index 00000000..2774e9bf --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextr_rs_l.c b/tests/tcg/mips/mips64-dsp/dextr_rs_l.c new file mode 100644 index 00000000..1a202fef --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextr_rs_w.c b/tests/tcg/mips/mips64-dsp/dextr_rs_w.c new file mode 100644 index 00000000..ebe5f99d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextr_s_h.c b/tests/tcg/mips/mips64-dsp/dextr_s_h.c new file mode 100644 index 00000000..1adb5549 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextr_w.c b/tests/tcg/mips/mips64-dsp/dextr_w.c new file mode 100644 index 00000000..79bed5da --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextrv_l.c b/tests/tcg/mips/mips64-dsp/dextrv_l.c new file mode 100644 index 00000000..2e6187f7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextrv_r_l.c b/tests/tcg/mips/mips64-dsp/dextrv_r_l.c new file mode 100644 index 00000000..b47a0177 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextrv_r_w.c b/tests/tcg/mips/mips64-dsp/dextrv_r_w.c new file mode 100644 index 00000000..cd201deb --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextrv_rs_l.c b/tests/tcg/mips/mips64-dsp/dextrv_rs_l.c new file mode 100644 index 00000000..6ce41854 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextrv_rs_w.c b/tests/tcg/mips/mips64-dsp/dextrv_rs_w.c new file mode 100644 index 00000000..a65183c0 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextrv_s_h.c b/tests/tcg/mips/mips64-dsp/dextrv_s_h.c new file mode 100644 index 00000000..87d3aeed --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dextrv_w.c b/tests/tcg/mips/mips64-dsp/dextrv_w.c new file mode 100644 index 00000000..973765c1 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dinsv.c b/tests/tcg/mips/mips64-dsp/dinsv.c new file mode 100644 index 00000000..f6192188 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dmadd.c b/tests/tcg/mips/mips64-dsp/dmadd.c new file mode 100644 index 00000000..fb226147 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dmaddu.c b/tests/tcg/mips/mips64-dsp/dmaddu.c new file mode 100644 index 00000000..39ab0c10 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dmsub.c b/tests/tcg/mips/mips64-dsp/dmsub.c new file mode 100644 index 00000000..16be6170 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dmsubu.c b/tests/tcg/mips/mips64-dsp/dmsubu.c new file mode 100644 index 00000000..cc4838ad --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dmthlip.c b/tests/tcg/mips/mips64-dsp/dmthlip.c new file mode 100644 index 00000000..027555fb --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpaq_s_w_ph.c b/tests/tcg/mips/mips64-dsp/dpaq_s_w_ph.c new file mode 100644 index 00000000..1bca9350 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpaq_s_w_qh.c b/tests/tcg/mips/mips64-dsp/dpaq_s_w_qh.c new file mode 100644 index 00000000..844a3474 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpaq_sa_l_pw.c b/tests/tcg/mips/mips64-dsp/dpaq_sa_l_pw.c new file mode 100644 index 00000000..1bb2ec2f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpaq_sa_l_w.c b/tests/tcg/mips/mips64-dsp/dpaq_sa_l_w.c new file mode 100644 index 00000000..f840cdd7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpau_h_obl.c b/tests/tcg/mips/mips64-dsp/dpau_h_obl.c new file mode 100644 index 00000000..54905e8f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpau_h_obr.c b/tests/tcg/mips/mips64-dsp/dpau_h_obr.c new file mode 100644 index 00000000..d7aa60b4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpau_h_qbl.c b/tests/tcg/mips/mips64-dsp/dpau_h_qbl.c new file mode 100644 index 00000000..fcfd7643 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpau_h_qbr.c b/tests/tcg/mips/mips64-dsp/dpau_h_qbr.c new file mode 100644 index 00000000..3282461a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpsq_s_w_ph.c b/tests/tcg/mips/mips64-dsp/dpsq_s_w_ph.c new file mode 100644 index 00000000..7660f037 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpsq_s_w_qh.c b/tests/tcg/mips/mips64-dsp/dpsq_s_w_qh.c new file mode 100644 index 00000000..2cc50c57 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpsq_sa_l_pw.c b/tests/tcg/mips/mips64-dsp/dpsq_sa_l_pw.c new file mode 100644 index 00000000..7fc2503f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpsq_sa_l_w.c b/tests/tcg/mips/mips64-dsp/dpsq_sa_l_w.c new file mode 100644 index 00000000..f55afc90 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpsu_h_obl.c b/tests/tcg/mips/mips64-dsp/dpsu_h_obl.c new file mode 100644 index 00000000..c0a8f4d7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpsu_h_obr.c b/tests/tcg/mips/mips64-dsp/dpsu_h_obr.c new file mode 100644 index 00000000..aa0d47a0 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpsu_h_qbl.c b/tests/tcg/mips/mips64-dsp/dpsu_h_qbl.c new file mode 100644 index 00000000..da6dbb61 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dpsu_h_qbr.c b/tests/tcg/mips/mips64-dsp/dpsu_h_qbr.c new file mode 100644 index 00000000..bf00b70a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dshilo.c b/tests/tcg/mips/mips64-dsp/dshilo.c new file mode 100644 index 00000000..f50584b9 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/dshilov.c b/tests/tcg/mips/mips64-dsp/dshilov.c new file mode 100644 index 00000000..792bd237 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extp.c b/tests/tcg/mips/mips64-dsp/extp.c new file mode 100644 index 00000000..c72f54ba --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extpdp.c b/tests/tcg/mips/mips64-dsp/extpdp.c new file mode 100644 index 00000000..f4301938 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extpdpv.c b/tests/tcg/mips/mips64-dsp/extpdpv.c new file mode 100644 index 00000000..ba57426d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extpv.c b/tests/tcg/mips/mips64-dsp/extpv.c new file mode 100644 index 00000000..158472bf --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extr_r_w.c b/tests/tcg/mips/mips64-dsp/extr_r_w.c new file mode 100644 index 00000000..94572ad1 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extr_rs_w.c b/tests/tcg/mips/mips64-dsp/extr_rs_w.c new file mode 100644 index 00000000..73551f96 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extr_s_h.c b/tests/tcg/mips/mips64-dsp/extr_s_h.c new file mode 100644 index 00000000..de10cb57 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extr_w.c b/tests/tcg/mips/mips64-dsp/extr_w.c new file mode 100644 index 00000000..bd695766 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extrv_r_w.c b/tests/tcg/mips/mips64-dsp/extrv_r_w.c new file mode 100644 index 00000000..83797297 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extrv_rs_w.c b/tests/tcg/mips/mips64-dsp/extrv_rs_w.c new file mode 100644 index 00000000..8707cd11 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extrv_s_h.c b/tests/tcg/mips/mips64-dsp/extrv_s_h.c new file mode 100644 index 00000000..b6dcaebc --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/extrv_w.c b/tests/tcg/mips/mips64-dsp/extrv_w.c new file mode 100644 index 00000000..8adffb39 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/head.S b/tests/tcg/mips/mips64-dsp/head.S new file mode 100644 index 00000000..9a099ae4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/insv.c b/tests/tcg/mips/mips64-dsp/insv.c new file mode 100644 index 00000000..fc5696f4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/io.h b/tests/tcg/mips/mips64-dsp/io.h new file mode 100644 index 00000000..b7db61d7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/lbux.c b/tests/tcg/mips/mips64-dsp/lbux.c new file mode 100644 index 00000000..dbdc87bf --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/ldx.c b/tests/tcg/mips/mips64-dsp/ldx.c new file mode 100644 index 00000000..787d9f00 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/lhx.c b/tests/tcg/mips/mips64-dsp/lhx.c new file mode 100644 index 00000000..2020e568 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/lwx.c b/tests/tcg/mips/mips64-dsp/lwx.c new file mode 100644 index 00000000..6a81414d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/madd.c b/tests/tcg/mips/mips64-dsp/madd.c new file mode 100644 index 00000000..de6e44fb --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maddu.c b/tests/tcg/mips/mips64-dsp/maddu.c new file mode 100644 index 00000000..e9f426a3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_s_l_pwl.c b/tests/tcg/mips/mips64-dsp/maq_s_l_pwl.c new file mode 100644 index 00000000..c196b435 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_s_l_pwr.c b/tests/tcg/mips/mips64-dsp/maq_s_l_pwr.c new file mode 100644 index 00000000..e2af69fe --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_s_w_phl.c b/tests/tcg/mips/mips64-dsp/maq_s_w_phl.c new file mode 100644 index 00000000..7dba8746 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_s_w_phr.c b/tests/tcg/mips/mips64-dsp/maq_s_w_phr.c new file mode 100644 index 00000000..138ee2a6 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_s_w_qhll.c b/tests/tcg/mips/mips64-dsp/maq_s_w_qhll.c new file mode 100644 index 00000000..234a0af2 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_s_w_qhlr.c b/tests/tcg/mips/mips64-dsp/maq_s_w_qhlr.c new file mode 100644 index 00000000..8768cbaa --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_s_w_qhrl.c b/tests/tcg/mips/mips64-dsp/maq_s_w_qhrl.c new file mode 100644 index 00000000..5006e2be --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_s_w_qhrr.c b/tests/tcg/mips/mips64-dsp/maq_s_w_qhrr.c new file mode 100644 index 00000000..1d213a51 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_sa_w_phl.c b/tests/tcg/mips/mips64-dsp/maq_sa_w_phl.c new file mode 100644 index 00000000..5530ffbe --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_sa_w_phr.c b/tests/tcg/mips/mips64-dsp/maq_sa_w_phr.c new file mode 100644 index 00000000..b611cfa9 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_sa_w_qhll.c b/tests/tcg/mips/mips64-dsp/maq_sa_w_qhll.c new file mode 100644 index 00000000..136ff2d7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_sa_w_qhlr.c b/tests/tcg/mips/mips64-dsp/maq_sa_w_qhlr.c new file mode 100644 index 00000000..dd0ae1cc --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrl.c b/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrl.c new file mode 100644 index 00000000..a3de6f8e --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrr.c b/tests/tcg/mips/mips64-dsp/maq_sa_w_qhrr.c new file mode 100644 index 00000000..f0217373 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mfhi.c b/tests/tcg/mips/mips64-dsp/mfhi.c new file mode 100644 index 00000000..ee915f79 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mflo.c b/tests/tcg/mips/mips64-dsp/mflo.c new file mode 100644 index 00000000..cdc646b5 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mips_boot.lds b/tests/tcg/mips/mips64-dsp/mips_boot.lds new file mode 100644 index 00000000..bd7c0c0f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/modsub.c b/tests/tcg/mips/mips64-dsp/modsub.c new file mode 100644 index 00000000..2c91cb4c --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/msub.c b/tests/tcg/mips/mips64-dsp/msub.c new file mode 100644 index 00000000..75066b59 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/msubu.c b/tests/tcg/mips/mips64-dsp/msubu.c new file mode 100644 index 00000000..55f8ae04 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mthi.c b/tests/tcg/mips/mips64-dsp/mthi.c new file mode 100644 index 00000000..85700513 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mthlip.c b/tests/tcg/mips/mips64-dsp/mthlip.c new file mode 100644 index 00000000..957cd426 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mtlo.c b/tests/tcg/mips/mips64-dsp/mtlo.c new file mode 100644 index 00000000..304fffbe --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhl.c b/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhl.c new file mode 100644 index 00000000..6c68d45a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhr.c b/tests/tcg/mips/mips64-dsp/muleq_s_pw_qhr.c new file mode 100644 index 00000000..fa8b41fd --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/muleq_s_w_phl.c b/tests/tcg/mips/mips64-dsp/muleq_s_w_phl.c new file mode 100644 index 00000000..997a9f64 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/muleq_s_w_phr.c b/tests/tcg/mips/mips64-dsp/muleq_s_w_phr.c new file mode 100644 index 00000000..0e594794 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbl.c b/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbl.c new file mode 100644 index 00000000..2f444c9f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbr.c b/tests/tcg/mips/mips64-dsp/muleu_s_ph_qbr.c new file mode 100644 index 00000000..8bd0e994 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/muleu_s_qh_obl.c b/tests/tcg/mips/mips64-dsp/muleu_s_qh_obl.c new file mode 100644 index 00000000..db0d386e --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/muleu_s_qh_obr.c b/tests/tcg/mips/mips64-dsp/muleu_s_qh_obr.c new file mode 100644 index 00000000..52ed9c09 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mulq_rs_ph.c b/tests/tcg/mips/mips64-dsp/mulq_rs_ph.c new file mode 100644 index 00000000..fd6233d4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mulq_rs_qh.c b/tests/tcg/mips/mips64-dsp/mulq_rs_qh.c new file mode 100644 index 00000000..7863c059 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mulsaq_s_l_pw.c b/tests/tcg/mips/mips64-dsp/mulsaq_s_l_pw.c new file mode 100644 index 00000000..02548f85 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mulsaq_s_w_qh.c b/tests/tcg/mips/mips64-dsp/mulsaq_s_w_qh.c new file mode 100644 index 00000000..92d7a0b4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/mult.c b/tests/tcg/mips/mips64-dsp/mult.c new file mode 100644 index 00000000..4a294d1a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/multu.c b/tests/tcg/mips/mips64-dsp/multu.c new file mode 100644 index 00000000..21a8a7c7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/packrl_ph.c b/tests/tcg/mips/mips64-dsp/packrl_ph.c new file mode 100644 index 00000000..3722b0ae --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/packrl_pw.c b/tests/tcg/mips/mips64-dsp/packrl_pw.c new file mode 100644 index 00000000..78074188 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/pick_ob.c b/tests/tcg/mips/mips64-dsp/pick_ob.c new file mode 100644 index 00000000..160049ff --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/pick_ph.c b/tests/tcg/mips/mips64-dsp/pick_ph.c new file mode 100644 index 00000000..8800c14d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/pick_pw.c b/tests/tcg/mips/mips64-dsp/pick_pw.c new file mode 100644 index 00000000..24d80f55 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/pick_qb.c b/tests/tcg/mips/mips64-dsp/pick_qb.c new file mode 100644 index 00000000..0d5de9db --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/pick_qh.c b/tests/tcg/mips/mips64-dsp/pick_qh.c new file mode 100644 index 00000000..aa2e2938 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceq_l_pwl.c b/tests/tcg/mips/mips64-dsp/preceq_l_pwl.c new file mode 100644 index 00000000..64551007 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceq_l_pwr.c b/tests/tcg/mips/mips64-dsp/preceq_l_pwr.c new file mode 100644 index 00000000..1e05339d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceq_pw_qhl.c b/tests/tcg/mips/mips64-dsp/preceq_pw_qhl.c new file mode 100644 index 00000000..f44b9404 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceq_pw_qhla.c b/tests/tcg/mips/mips64-dsp/preceq_pw_qhla.c new file mode 100644 index 00000000..f0f78f43 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceq_pw_qhr.c b/tests/tcg/mips/mips64-dsp/preceq_pw_qhr.c new file mode 100644 index 00000000..709d4f90 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceq_pw_qhra.c b/tests/tcg/mips/mips64-dsp/preceq_pw_qhra.c new file mode 100644 index 00000000..4d071ec8 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceq_w_phl.c b/tests/tcg/mips/mips64-dsp/preceq_w_phl.c new file mode 100644 index 00000000..4ed3fc03 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceq_w_phr.c b/tests/tcg/mips/mips64-dsp/preceq_w_phr.c new file mode 100644 index 00000000..e2ea0933 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precequ_ph_qbl.c b/tests/tcg/mips/mips64-dsp/precequ_ph_qbl.c new file mode 100644 index 00000000..17b73311 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precequ_ph_qbla.c b/tests/tcg/mips/mips64-dsp/precequ_ph_qbla.c new file mode 100644 index 00000000..15e94946 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precequ_ph_qbr.c b/tests/tcg/mips/mips64-dsp/precequ_ph_qbr.c new file mode 100644 index 00000000..495368ce --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precequ_ph_qbra.c b/tests/tcg/mips/mips64-dsp/precequ_ph_qbra.c new file mode 100644 index 00000000..7c663697 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precequ_qh_obl.c b/tests/tcg/mips/mips64-dsp/precequ_qh_obl.c new file mode 100644 index 00000000..176d2365 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precequ_qh_obla.c b/tests/tcg/mips/mips64-dsp/precequ_qh_obla.c new file mode 100644 index 00000000..93a36a48 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precequ_qh_obr.c b/tests/tcg/mips/mips64-dsp/precequ_qh_obr.c new file mode 100644 index 00000000..12147308 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precequ_qh_obra.c b/tests/tcg/mips/mips64-dsp/precequ_qh_obra.c new file mode 100644 index 00000000..3aa0e096 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceu_ph_qbl.c b/tests/tcg/mips/mips64-dsp/preceu_ph_qbl.c new file mode 100644 index 00000000..81f7917c --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceu_ph_qbla.c b/tests/tcg/mips/mips64-dsp/preceu_ph_qbla.c new file mode 100644 index 00000000..38cf6a62 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceu_ph_qbr.c b/tests/tcg/mips/mips64-dsp/preceu_ph_qbr.c new file mode 100644 index 00000000..70c32b67 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceu_ph_qbra.c b/tests/tcg/mips/mips64-dsp/preceu_ph_qbra.c new file mode 100644 index 00000000..c6638aaa --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceu_qh_obl.c b/tests/tcg/mips/mips64-dsp/preceu_qh_obl.c new file mode 100644 index 00000000..63f9373b --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceu_qh_obla.c b/tests/tcg/mips/mips64-dsp/preceu_qh_obla.c new file mode 100644 index 00000000..5fb65e40 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceu_qh_obr.c b/tests/tcg/mips/mips64-dsp/preceu_qh_obr.c new file mode 100644 index 00000000..9af3b637 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/preceu_qh_obra.c b/tests/tcg/mips/mips64-dsp/preceu_qh_obra.c new file mode 100644 index 00000000..fd040833 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precr_ob_qh.c b/tests/tcg/mips/mips64-dsp/precr_ob_qh.c new file mode 100644 index 00000000..ce2da79a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precr_sra_qh_pw.c b/tests/tcg/mips/mips64-dsp/precr_sra_qh_pw.c new file mode 100644 index 00000000..8bb16de9 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precr_sra_r_qh_pw.c b/tests/tcg/mips/mips64-dsp/precr_sra_r_qh_pw.c new file mode 100644 index 00000000..734ac322 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precrq_ob_qh.c b/tests/tcg/mips/mips64-dsp/precrq_ob_qh.c new file mode 100644 index 00000000..4f61b170 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precrq_ph_w.c b/tests/tcg/mips/mips64-dsp/precrq_ph_w.c new file mode 100644 index 00000000..f0946abd --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precrq_pw_l.c b/tests/tcg/mips/mips64-dsp/precrq_pw_l.c new file mode 100644 index 00000000..da957c07 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precrq_qb_ph.c b/tests/tcg/mips/mips64-dsp/precrq_qb_ph.c new file mode 100644 index 00000000..f417c9f3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precrq_qh_pw.c b/tests/tcg/mips/mips64-dsp/precrq_qh_pw.c new file mode 100644 index 00000000..4a4ffef8 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precrq_rs_ph_w.c b/tests/tcg/mips/mips64-dsp/precrq_rs_ph_w.c new file mode 100644 index 00000000..61da3331 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precrq_rs_qh_pw.c b/tests/tcg/mips/mips64-dsp/precrq_rs_qh_pw.c new file mode 100644 index 00000000..ac78728a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precrqu_s_ob_qh.c b/tests/tcg/mips/mips64-dsp/precrqu_s_ob_qh.c new file mode 100644 index 00000000..e27c36b7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/precrqu_s_qb_ph.c b/tests/tcg/mips/mips64-dsp/precrqu_s_qb_ph.c new file mode 100644 index 00000000..cb1fee45 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/prependd.c b/tests/tcg/mips/mips64-dsp/prependd.c new file mode 100644 index 00000000..b4208c2d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/prependw.c b/tests/tcg/mips/mips64-dsp/prependw.c new file mode 100644 index 00000000..d91bd202 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/printf.c b/tests/tcg/mips/mips64-dsp/printf.c new file mode 100644 index 00000000..cf8676d3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/raddu_l_ob.c b/tests/tcg/mips/mips64-dsp/raddu_l_ob.c new file mode 100644 index 00000000..76ddf25f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/raddu_w_qb.c b/tests/tcg/mips/mips64-dsp/raddu_w_qb.c new file mode 100644 index 00000000..c9d6535b --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/rddsp.c b/tests/tcg/mips/mips64-dsp/rddsp.c new file mode 100644 index 00000000..71655724 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/repl_ob.c b/tests/tcg/mips/mips64-dsp/repl_ob.c new file mode 100644 index 00000000..20cb7801 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/repl_ph.c b/tests/tcg/mips/mips64-dsp/repl_ph.c new file mode 100644 index 00000000..11d29bdb --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/repl_pw.c b/tests/tcg/mips/mips64-dsp/repl_pw.c new file mode 100644 index 00000000..d35376a2 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/repl_qb.c b/tests/tcg/mips/mips64-dsp/repl_qb.c new file mode 100644 index 00000000..592feaec --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/repl_qh.c b/tests/tcg/mips/mips64-dsp/repl_qh.c new file mode 100644 index 00000000..82afc371 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/replv_ob.c b/tests/tcg/mips/mips64-dsp/replv_ob.c new file mode 100644 index 00000000..31ff3186 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/replv_ph.c b/tests/tcg/mips/mips64-dsp/replv_ph.c new file mode 100644 index 00000000..0af7a36b --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/replv_pw.c b/tests/tcg/mips/mips64-dsp/replv_pw.c new file mode 100644 index 00000000..e1789af4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/replv_qb.c b/tests/tcg/mips/mips64-dsp/replv_qb.c new file mode 100644 index 00000000..d99298c3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shilo.c b/tests/tcg/mips/mips64-dsp/shilo.c new file mode 100644 index 00000000..5f454f69 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shilov.c b/tests/tcg/mips/mips64-dsp/shilov.c new file mode 100644 index 00000000..e82615a8 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shll_ob.c b/tests/tcg/mips/mips64-dsp/shll_ob.c new file mode 100644 index 00000000..7dcb58ff --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shll_ph.c b/tests/tcg/mips/mips64-dsp/shll_ph.c new file mode 100644 index 00000000..42b462d2 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shll_pw.c b/tests/tcg/mips/mips64-dsp/shll_pw.c new file mode 100644 index 00000000..d7878b27 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shll_qb.c b/tests/tcg/mips/mips64-dsp/shll_qb.c new file mode 100644 index 00000000..c21ab669 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shll_qh.c b/tests/tcg/mips/mips64-dsp/shll_qh.c new file mode 100644 index 00000000..1380825a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shll_s_ph.c b/tests/tcg/mips/mips64-dsp/shll_s_ph.c new file mode 100644 index 00000000..1cf5d6da --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shll_s_pw.c b/tests/tcg/mips/mips64-dsp/shll_s_pw.c new file mode 100644 index 00000000..e38f6860 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shll_s_qh.c b/tests/tcg/mips/mips64-dsp/shll_s_qh.c new file mode 100644 index 00000000..f2f57fa2 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shll_s_w.c b/tests/tcg/mips/mips64-dsp/shll_s_w.c new file mode 100644 index 00000000..57800615 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shllv_ob.c b/tests/tcg/mips/mips64-dsp/shllv_ob.c new file mode 100644 index 00000000..96a2e6f5 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shllv_ph.c b/tests/tcg/mips/mips64-dsp/shllv_ph.c new file mode 100644 index 00000000..532291f3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shllv_pw.c b/tests/tcg/mips/mips64-dsp/shllv_pw.c new file mode 100644 index 00000000..8d4ec295 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shllv_qb.c b/tests/tcg/mips/mips64-dsp/shllv_qb.c new file mode 100644 index 00000000..e49356b8 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shllv_qh.c b/tests/tcg/mips/mips64-dsp/shllv_qh.c new file mode 100644 index 00000000..0de4077e --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shllv_s_ph.c b/tests/tcg/mips/mips64-dsp/shllv_s_ph.c new file mode 100644 index 00000000..7e69f941 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shllv_s_pw.c b/tests/tcg/mips/mips64-dsp/shllv_s_pw.c new file mode 100644 index 00000000..f8dc8d29 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shllv_s_qh.c b/tests/tcg/mips/mips64-dsp/shllv_s_qh.c new file mode 100644 index 00000000..db3832d0 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shllv_s_w.c b/tests/tcg/mips/mips64-dsp/shllv_s_w.c new file mode 100644 index 00000000..5f6af8b8 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shra_ob.c b/tests/tcg/mips/mips64-dsp/shra_ob.c new file mode 100644 index 00000000..d7fcfa81 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shra_ph.c b/tests/tcg/mips/mips64-dsp/shra_ph.c new file mode 100644 index 00000000..a2dc0147 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shra_pw.c b/tests/tcg/mips/mips64-dsp/shra_pw.c new file mode 100644 index 00000000..33b1b8fe --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shra_qh.c b/tests/tcg/mips/mips64-dsp/shra_qh.c new file mode 100644 index 00000000..85dbfef3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shra_r_ob.c b/tests/tcg/mips/mips64-dsp/shra_r_ob.c new file mode 100644 index 00000000..18470944 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shra_r_ph.c b/tests/tcg/mips/mips64-dsp/shra_r_ph.c new file mode 100644 index 00000000..e0943ad4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shra_r_pw.c b/tests/tcg/mips/mips64-dsp/shra_r_pw.c new file mode 100644 index 00000000..6a86e684 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shra_r_qh.c b/tests/tcg/mips/mips64-dsp/shra_r_qh.c new file mode 100644 index 00000000..d5c2110e --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shra_r_w.c b/tests/tcg/mips/mips64-dsp/shra_r_w.c new file mode 100644 index 00000000..36d2c9c8 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrav_ph.c b/tests/tcg/mips/mips64-dsp/shrav_ph.c new file mode 100644 index 00000000..1b4e9837 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrav_pw.c b/tests/tcg/mips/mips64-dsp/shrav_pw.c new file mode 100644 index 00000000..e19d5157 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrav_qh.c b/tests/tcg/mips/mips64-dsp/shrav_qh.c new file mode 100644 index 00000000..dc92e09d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrav_r_ph.c b/tests/tcg/mips/mips64-dsp/shrav_r_ph.c new file mode 100644 index 00000000..350d5294 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrav_r_pw.c b/tests/tcg/mips/mips64-dsp/shrav_r_pw.c new file mode 100644 index 00000000..25b05459 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrav_r_qh.c b/tests/tcg/mips/mips64-dsp/shrav_r_qh.c new file mode 100644 index 00000000..fd187a1e --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrav_r_w.c b/tests/tcg/mips/mips64-dsp/shrav_r_w.c new file mode 100644 index 00000000..3766c725 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrl_ob.c b/tests/tcg/mips/mips64-dsp/shrl_ob.c new file mode 100644 index 00000000..a1145713 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrl_qb.c b/tests/tcg/mips/mips64-dsp/shrl_qb.c new file mode 100644 index 00000000..c0e36dba --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrl_qh.c b/tests/tcg/mips/mips64-dsp/shrl_qh.c new file mode 100644 index 00000000..c1562463 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrlv_ob.c b/tests/tcg/mips/mips64-dsp/shrlv_ob.c new file mode 100644 index 00000000..cb39c467 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrlv_qb.c b/tests/tcg/mips/mips64-dsp/shrlv_qb.c new file mode 100644 index 00000000..5616aa9c --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/shrlv_qh.c b/tests/tcg/mips/mips64-dsp/shrlv_qh.c new file mode 100644 index 00000000..05de2fd6 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subq_ph.c b/tests/tcg/mips/mips64-dsp/subq_ph.c new file mode 100644 index 00000000..6a1b1861 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subq_pw.c b/tests/tcg/mips/mips64-dsp/subq_pw.c new file mode 100644 index 00000000..32f96ba4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subq_qh.c b/tests/tcg/mips/mips64-dsp/subq_qh.c new file mode 100644 index 00000000..76d5f0a1 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subq_s_ph.c b/tests/tcg/mips/mips64-dsp/subq_s_ph.c new file mode 100644 index 00000000..0b162f07 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subq_s_pw.c b/tests/tcg/mips/mips64-dsp/subq_s_pw.c new file mode 100644 index 00000000..e8e0b056 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subq_s_qh.c b/tests/tcg/mips/mips64-dsp/subq_s_qh.c new file mode 100644 index 00000000..4053b6b8 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subq_s_w.c b/tests/tcg/mips/mips64-dsp/subq_s_w.c new file mode 100644 index 00000000..91d32da1 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subu_ob.c b/tests/tcg/mips/mips64-dsp/subu_ob.c new file mode 100644 index 00000000..f6709671 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subu_qb.c b/tests/tcg/mips/mips64-dsp/subu_qb.c new file mode 100644 index 00000000..9eb80df3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subu_s_ob.c b/tests/tcg/mips/mips64-dsp/subu_s_ob.c new file mode 100644 index 00000000..5df64e5f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/subu_s_qb.c b/tests/tcg/mips/mips64-dsp/subu_s_qb.c new file mode 100644 index 00000000..9de76f4a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dsp/wrdsp.c b/tests/tcg/mips/mips64-dsp/wrdsp.c new file mode 100644 index 00000000..3033fd88 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/.directory b/tests/tcg/mips/mips64-dspr2/.directory new file mode 100644 index 00000000..c75a9145 --- /dev/null +++ b/tests/tcg/mips/mips64-dspr2/.directory @@ -0,0 +1,2 @@ +[Dolphin] +Timestamp=2012,8,3,16,41,52 diff --git a/tests/tcg/mips/mips64-dspr2/Makefile b/tests/tcg/mips/mips64-dspr2/Makefile new file mode 100644 index 00000000..ba44bb9c --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/absq_s_qb.c b/tests/tcg/mips/mips64-dspr2/absq_s_qb.c new file mode 100644 index 00000000..f7aec3e5 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/addqh_ph.c b/tests/tcg/mips/mips64-dspr2/addqh_ph.c new file mode 100644 index 00000000..6b43cb8d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/addqh_r_ph.c b/tests/tcg/mips/mips64-dspr2/addqh_r_ph.c new file mode 100644 index 00000000..890ec98d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/addqh_r_w.c b/tests/tcg/mips/mips64-dspr2/addqh_r_w.c new file mode 100644 index 00000000..d324decb --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/addqh_w.c b/tests/tcg/mips/mips64-dspr2/addqh_w.c new file mode 100644 index 00000000..78559e67 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/addu_ph.c b/tests/tcg/mips/mips64-dspr2/addu_ph.c new file mode 100644 index 00000000..d64c8cde --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/addu_qh.c b/tests/tcg/mips/mips64-dspr2/addu_qh.c new file mode 100644 index 00000000..edcbf342 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/addu_s_ph.c b/tests/tcg/mips/mips64-dspr2/addu_s_ph.c new file mode 100644 index 00000000..9250edb4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/addu_s_qh.c b/tests/tcg/mips/mips64-dspr2/addu_s_qh.c new file mode 100644 index 00000000..b0c16262 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/adduh_ob.c b/tests/tcg/mips/mips64-dspr2/adduh_ob.c new file mode 100644 index 00000000..9b309f6f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/adduh_qb.c b/tests/tcg/mips/mips64-dspr2/adduh_qb.c new file mode 100644 index 00000000..796b409a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/adduh_r_ob.c b/tests/tcg/mips/mips64-dspr2/adduh_r_ob.c new file mode 100644 index 00000000..832de833 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/adduh_r_qb.c b/tests/tcg/mips/mips64-dspr2/adduh_r_qb.c new file mode 100644 index 00000000..ae65fa5e --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/append.c b/tests/tcg/mips/mips64-dspr2/append.c new file mode 100644 index 00000000..68a7cecc --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/balign.c b/tests/tcg/mips/mips64-dspr2/balign.c new file mode 100644 index 00000000..7fbe8157 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_ob.c b/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_ob.c new file mode 100644 index 00000000..61217f38 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_qb.c b/tests/tcg/mips/mips64-dspr2/cmpgdu_eq_qb.c new file mode 100644 index 00000000..c63f6480 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/cmpgdu_le_ob.c b/tests/tcg/mips/mips64-dspr2/cmpgdu_le_ob.c new file mode 100644 index 00000000..b3da0981 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/cmpgdu_le_qb.c b/tests/tcg/mips/mips64-dspr2/cmpgdu_le_qb.c new file mode 100644 index 00000000..f0a60ea4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_ob.c b/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_ob.c new file mode 100644 index 00000000..d80b4e6a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_qb.c b/tests/tcg/mips/mips64-dspr2/cmpgdu_lt_qb.c new file mode 100644 index 00000000..a71e4e30 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dbalign.c b/tests/tcg/mips/mips64-dspr2/dbalign.c new file mode 100644 index 00000000..c7431b18 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dpa_w_ph.c b/tests/tcg/mips/mips64-dspr2/dpa_w_ph.c new file mode 100644 index 00000000..39dc99aa --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dpa_w_qh.c b/tests/tcg/mips/mips64-dspr2/dpa_w_qh.c new file mode 100644 index 00000000..1411e44b --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dpaqx_s_w_ph.c b/tests/tcg/mips/mips64-dspr2/dpaqx_s_w_ph.c new file mode 100644 index 00000000..51252fb9 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dpaqx_sa_w_ph.c b/tests/tcg/mips/mips64-dspr2/dpaqx_sa_w_ph.c new file mode 100644 index 00000000..18d6b3a9 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dpax_w_ph.c b/tests/tcg/mips/mips64-dspr2/dpax_w_ph.c new file mode 100644 index 00000000..9d595fc1 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dps_w_ph.c b/tests/tcg/mips/mips64-dspr2/dps_w_ph.c new file mode 100644 index 00000000..99f292ec --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dps_w_qh.c b/tests/tcg/mips/mips64-dspr2/dps_w_qh.c new file mode 100644 index 00000000..61277eb3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dpsqx_s_w_ph.c b/tests/tcg/mips/mips64-dspr2/dpsqx_s_w_ph.c new file mode 100644 index 00000000..ba46a926 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dpsqx_sa_w_ph.c b/tests/tcg/mips/mips64-dspr2/dpsqx_sa_w_ph.c new file mode 100644 index 00000000..24c88813 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/dpsx_w_ph.c b/tests/tcg/mips/mips64-dspr2/dpsx_w_ph.c new file mode 100644 index 00000000..b6291b5e --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/head.S b/tests/tcg/mips/mips64-dspr2/head.S new file mode 100644 index 00000000..9a099ae4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/io.h b/tests/tcg/mips/mips64-dspr2/io.h new file mode 100644 index 00000000..b7db61d7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/mips_boot.lds b/tests/tcg/mips/mips64-dspr2/mips_boot.lds new file mode 100644 index 00000000..bd7c0c0f --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/mul_ph.c b/tests/tcg/mips/mips64-dspr2/mul_ph.c new file mode 100644 index 00000000..5a3d05cb --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/mul_s_ph.c b/tests/tcg/mips/mips64-dspr2/mul_s_ph.c new file mode 100644 index 00000000..7c8b2c71 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/mulq_rs_w.c b/tests/tcg/mips/mips64-dspr2/mulq_rs_w.c new file mode 100644 index 00000000..ffdc66d5 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/mulq_s_ph.c b/tests/tcg/mips/mips64-dspr2/mulq_s_ph.c new file mode 100644 index 00000000..b8c20c68 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/mulq_s_w.c b/tests/tcg/mips/mips64-dspr2/mulq_s_w.c new file mode 100644 index 00000000..db74b713 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/mulsa_w_ph.c b/tests/tcg/mips/mips64-dspr2/mulsa_w_ph.c new file mode 100644 index 00000000..5b22a60a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/mulsaq_s_w_ph.c b/tests/tcg/mips/mips64-dspr2/mulsaq_s_w_ph.c new file mode 100644 index 00000000..835a73d4 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/precr_qb_ph.c b/tests/tcg/mips/mips64-dspr2/precr_qb_ph.c new file mode 100644 index 00000000..80d5e8dc --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/precr_sra_ph_w.c b/tests/tcg/mips/mips64-dspr2/precr_sra_ph_w.c new file mode 100644 index 00000000..b1d7bcdf --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/precr_sra_r_ph_w.c b/tests/tcg/mips/mips64-dspr2/precr_sra_r_ph_w.c new file mode 100644 index 00000000..62d220dc --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/prepend.c b/tests/tcg/mips/mips64-dspr2/prepend.c new file mode 100644 index 00000000..4ab083e9 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/printf.c b/tests/tcg/mips/mips64-dspr2/printf.c new file mode 100644 index 00000000..cf8676d3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/shra_qb.c b/tests/tcg/mips/mips64-dspr2/shra_qb.c new file mode 100644 index 00000000..cac31023 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/shra_r_qb.c b/tests/tcg/mips/mips64-dspr2/shra_r_qb.c new file mode 100644 index 00000000..9c64f75b --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/shrav_ob.c b/tests/tcg/mips/mips64-dspr2/shrav_ob.c new file mode 100644 index 00000000..fbdfbab3 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/shrav_qb.c b/tests/tcg/mips/mips64-dspr2/shrav_qb.c new file mode 100644 index 00000000..a716203d --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/shrav_r_ob.c b/tests/tcg/mips/mips64-dspr2/shrav_r_ob.c new file mode 100644 index 00000000..b80100a7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/shrav_r_qb.c b/tests/tcg/mips/mips64-dspr2/shrav_r_qb.c new file mode 100644 index 00000000..009080b2 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/shrl_ph.c b/tests/tcg/mips/mips64-dspr2/shrl_ph.c new file mode 100644 index 00000000..e32d9766 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/shrlv_ph.c b/tests/tcg/mips/mips64-dspr2/shrlv_ph.c new file mode 100644 index 00000000..58c5488b --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subqh_ph.c b/tests/tcg/mips/mips64-dspr2/subqh_ph.c new file mode 100644 index 00000000..90374019 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subqh_r_ph.c b/tests/tcg/mips/mips64-dspr2/subqh_r_ph.c new file mode 100644 index 00000000..b8f9d2fe --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subqh_r_w.c b/tests/tcg/mips/mips64-dspr2/subqh_r_w.c new file mode 100644 index 00000000..b025e40a --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subqh_w.c b/tests/tcg/mips/mips64-dspr2/subqh_w.c new file mode 100644 index 00000000..65f17603 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subu_ph.c b/tests/tcg/mips/mips64-dspr2/subu_ph.c new file mode 100644 index 00000000..60a6b1b7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subu_qh.c b/tests/tcg/mips/mips64-dspr2/subu_qh.c new file mode 100644 index 00000000..911cb349 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subu_s_ph.c b/tests/tcg/mips/mips64-dspr2/subu_s_ph.c new file mode 100644 index 00000000..ae32cc06 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subu_s_qh.c b/tests/tcg/mips/mips64-dspr2/subu_s_qh.c new file mode 100644 index 00000000..de7a29e7 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subuh_ob.c b/tests/tcg/mips/mips64-dspr2/subuh_ob.c new file mode 100644 index 00000000..3fc452bf --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subuh_qb.c b/tests/tcg/mips/mips64-dspr2/subuh_qb.c new file mode 100644 index 00000000..aac7a834 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subuh_r_ob.c b/tests/tcg/mips/mips64-dspr2/subuh_r_ob.c new file mode 100644 index 00000000..fc20ffd0 --- /dev/null +++ b/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/tests/tcg/mips/mips64-dspr2/subuh_r_qb.c b/tests/tcg/mips/mips64-dspr2/subuh_r_qb.c new file mode 100644 index 00000000..66d46804 --- /dev/null +++ b/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/tests/tcg/openrisc/Makefile b/tests/tcg/openrisc/Makefile new file mode 100644 index 00000000..7e658887 --- /dev/null +++ b/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/tests/tcg/openrisc/test_add.c b/tests/tcg/openrisc/test_add.c new file mode 100644 index 00000000..3d23592e --- /dev/null +++ b/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/tests/tcg/openrisc/test_addc.c b/tests/tcg/openrisc/test_addc.c new file mode 100644 index 00000000..a8f756a6 --- /dev/null +++ b/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/tests/tcg/openrisc/test_addi.c b/tests/tcg/openrisc/test_addi.c new file mode 100644 index 00000000..bbf5a5ff --- /dev/null +++ b/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/tests/tcg/openrisc/test_addic.c b/tests/tcg/openrisc/test_addic.c new file mode 100644 index 00000000..857aaa13 --- /dev/null +++ b/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/tests/tcg/openrisc/test_and_or.c b/tests/tcg/openrisc/test_and_or.c new file mode 100644 index 00000000..810d868c --- /dev/null +++ b/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/tests/tcg/openrisc/test_bf.c b/tests/tcg/openrisc/test_bf.c new file mode 100644 index 00000000..79f3fb99 --- /dev/null +++ b/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/tests/tcg/openrisc/test_bnf.c b/tests/tcg/openrisc/test_bnf.c new file mode 100644 index 00000000..f716215f --- /dev/null +++ b/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/tests/tcg/openrisc/test_div.c b/tests/tcg/openrisc/test_div.c new file mode 100644 index 00000000..9b65f6e6 --- /dev/null +++ b/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/tests/tcg/openrisc/test_divu.c b/tests/tcg/openrisc/test_divu.c new file mode 100644 index 00000000..bff9e3ea --- /dev/null +++ b/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/tests/tcg/openrisc/test_extx.c b/tests/tcg/openrisc/test_extx.c new file mode 100644 index 00000000..09221484 --- /dev/null +++ b/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/tests/tcg/openrisc/test_fx.c b/tests/tcg/openrisc/test_fx.c new file mode 100644 index 00000000..df86000d --- /dev/null +++ b/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/tests/tcg/openrisc/test_j.c b/tests/tcg/openrisc/test_j.c new file mode 100644 index 00000000..9ddf8bfb --- /dev/null +++ b/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/tests/tcg/openrisc/test_jal.c b/tests/tcg/openrisc/test_jal.c new file mode 100644 index 00000000..7e2da401 --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_add.c b/tests/tcg/openrisc/test_lf_add.c new file mode 100644 index 00000000..e00212da --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_div.c b/tests/tcg/openrisc/test_lf_div.c new file mode 100644 index 00000000..70b5d1c1 --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_eqs.c b/tests/tcg/openrisc/test_lf_eqs.c new file mode 100644 index 00000000..a176bd6f --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_ges.c b/tests/tcg/openrisc/test_lf_ges.c new file mode 100644 index 00000000..98e7f50b --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_gts.c b/tests/tcg/openrisc/test_lf_gts.c new file mode 100644 index 00000000..f3df2795 --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_les.c b/tests/tcg/openrisc/test_lf_les.c new file mode 100644 index 00000000..046c511d --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_lts.c b/tests/tcg/openrisc/test_lf_lts.c new file mode 100644 index 00000000..fa56721d --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_mul.c b/tests/tcg/openrisc/test_lf_mul.c new file mode 100644 index 00000000..bc8ad800 --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_nes.c b/tests/tcg/openrisc/test_lf_nes.c new file mode 100644 index 00000000..61363100 --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_rem.c b/tests/tcg/openrisc/test_lf_rem.c new file mode 100644 index 00000000..bd6090d6 --- /dev/null +++ b/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/tests/tcg/openrisc/test_lf_sub.c b/tests/tcg/openrisc/test_lf_sub.c new file mode 100644 index 00000000..5ee9b039 --- /dev/null +++ b/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/tests/tcg/openrisc/test_logic.c b/tests/tcg/openrisc/test_logic.c new file mode 100644 index 00000000..46d173f4 --- /dev/null +++ b/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/tests/tcg/openrisc/test_lx.c b/tests/tcg/openrisc/test_lx.c new file mode 100644 index 00000000..792e3d5c --- /dev/null +++ b/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/tests/tcg/openrisc/test_movhi.c b/tests/tcg/openrisc/test_movhi.c new file mode 100644 index 00000000..737f75b9 --- /dev/null +++ b/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/tests/tcg/openrisc/test_mul.c b/tests/tcg/openrisc/test_mul.c new file mode 100644 index 00000000..130101fd --- /dev/null +++ b/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/tests/tcg/openrisc/test_muli.c b/tests/tcg/openrisc/test_muli.c new file mode 100644 index 00000000..f1042e98 --- /dev/null +++ b/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/tests/tcg/openrisc/test_mulu.c b/tests/tcg/openrisc/test_mulu.c new file mode 100644 index 00000000..2d1e97d1 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfeq.c b/tests/tcg/openrisc/test_sfeq.c new file mode 100644 index 00000000..bd7f875b --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfeqi.c b/tests/tcg/openrisc/test_sfeqi.c new file mode 100644 index 00000000..57426132 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfges.c b/tests/tcg/openrisc/test_sfges.c new file mode 100644 index 00000000..23761d7f --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfgesi.c b/tests/tcg/openrisc/test_sfgesi.c new file mode 100644 index 00000000..54a2d51c --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfgeu.c b/tests/tcg/openrisc/test_sfgeu.c new file mode 100644 index 00000000..2a491d91 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfgeui.c b/tests/tcg/openrisc/test_sfgeui.c new file mode 100644 index 00000000..40af35c6 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfgts.c b/tests/tcg/openrisc/test_sfgts.c new file mode 100644 index 00000000..4481a9cc --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfgtsi.c b/tests/tcg/openrisc/test_sfgtsi.c new file mode 100644 index 00000000..7366e129 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfgtu.c b/tests/tcg/openrisc/test_sfgtu.c new file mode 100644 index 00000000..da286891 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfgtui.c b/tests/tcg/openrisc/test_sfgtui.c new file mode 100644 index 00000000..565d44f1 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfles.c b/tests/tcg/openrisc/test_sfles.c new file mode 100644 index 00000000..f5735228 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sflesi.c b/tests/tcg/openrisc/test_sflesi.c new file mode 100644 index 00000000..16fe6053 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfleu.c b/tests/tcg/openrisc/test_sfleu.c new file mode 100644 index 00000000..be0a3c3f --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfleui.c b/tests/tcg/openrisc/test_sfleui.c new file mode 100644 index 00000000..38d3c897 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sflts.c b/tests/tcg/openrisc/test_sflts.c new file mode 100644 index 00000000..7deeb48d --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfltsi.c b/tests/tcg/openrisc/test_sfltsi.c new file mode 100644 index 00000000..3cb1f028 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfltu.c b/tests/tcg/openrisc/test_sfltu.c new file mode 100644 index 00000000..7ed3b268 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfltui.c b/tests/tcg/openrisc/test_sfltui.c new file mode 100644 index 00000000..a5cb9f6a --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfne.c b/tests/tcg/openrisc/test_sfne.c new file mode 100644 index 00000000..b33a35cf --- /dev/null +++ b/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/tests/tcg/openrisc/test_sfnei.c b/tests/tcg/openrisc/test_sfnei.c new file mode 100644 index 00000000..d311c9e6 --- /dev/null +++ b/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/tests/tcg/openrisc/test_sub.c b/tests/tcg/openrisc/test_sub.c new file mode 100644 index 00000000..474ec605 --- /dev/null +++ b/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/tests/tcg/pi_10.com b/tests/tcg/pi_10.com Binary files differnew file mode 100644 index 00000000..8993ba1a --- /dev/null +++ b/tests/tcg/pi_10.com diff --git a/tests/tcg/runcom.c b/tests/tcg/runcom.c new file mode 100644 index 00000000..d60342bf --- /dev/null +++ b/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/tests/tcg/sha1.c b/tests/tcg/sha1.c new file mode 100644 index 00000000..93b7c8e8 --- /dev/null +++ b/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/tests/tcg/test-arm-iwmmxt.s b/tests/tcg/test-arm-iwmmxt.s new file mode 100644 index 00000000..d647f940 --- /dev/null +++ b/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/tests/tcg/test-i386-code16.S b/tests/tcg/test-i386-code16.S new file mode 100644 index 00000000..816c24b9 --- /dev/null +++ b/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/tests/tcg/test-i386-fprem.c b/tests/tcg/test-i386-fprem.c new file mode 100644 index 00000000..e91fb1ae --- /dev/null +++ b/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/tests/tcg/test-i386-muldiv.h b/tests/tcg/test-i386-muldiv.h new file mode 100644 index 00000000..015f59e1 --- /dev/null +++ b/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/tests/tcg/test-i386-shift.h b/tests/tcg/test-i386-shift.h new file mode 100644 index 00000000..3d8f84bf --- /dev/null +++ b/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/tests/tcg/test-i386-ssse3.c b/tests/tcg/test-i386-ssse3.c new file mode 100644 index 00000000..0a42bd03 --- /dev/null +++ b/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/tests/tcg/test-i386-vm86.S b/tests/tcg/test-i386-vm86.S new file mode 100644 index 00000000..3bb96c99 --- /dev/null +++ b/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/tests/tcg/test-i386.c b/tests/tcg/test-i386.c new file mode 100644 index 00000000..b05572b7 --- /dev/null +++ b/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/tests/tcg/test-i386.h b/tests/tcg/test-i386.h new file mode 100644 index 00000000..75106b8c --- /dev/null +++ b/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/tests/tcg/test-mmap.c b/tests/tcg/test-mmap.c new file mode 100644 index 00000000..3982fa2c --- /dev/null +++ b/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/tests/tcg/test_path.c b/tests/tcg/test_path.c new file mode 100644 index 00000000..1c29bce2 --- /dev/null +++ b/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/tests/tcg/testthread.c b/tests/tcg/testthread.c new file mode 100644 index 00000000..2679af11 --- /dev/null +++ b/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/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile new file mode 100644 index 00000000..522a63e3 --- /dev/null +++ b/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/tests/tcg/xtensa/crt.S b/tests/tcg/xtensa/crt.S new file mode 100644 index 00000000..d9846aca --- /dev/null +++ b/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/tests/tcg/xtensa/linker.ld.S b/tests/tcg/xtensa/linker.ld.S new file mode 100644 index 00000000..f1e7fa9f --- /dev/null +++ b/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/tests/tcg/xtensa/macros.inc b/tests/tcg/xtensa/macros.inc new file mode 100644 index 00000000..4ebd30ab --- /dev/null +++ b/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/tests/tcg/xtensa/test_b.S b/tests/tcg/xtensa/test_b.S new file mode 100644 index 00000000..8e81f956 --- /dev/null +++ b/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/tests/tcg/xtensa/test_bi.S b/tests/tcg/xtensa/test_bi.S new file mode 100644 index 00000000..4f94c0c7 --- /dev/null +++ b/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/tests/tcg/xtensa/test_boolean.S b/tests/tcg/xtensa/test_boolean.S new file mode 100644 index 00000000..eac40e09 --- /dev/null +++ b/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/tests/tcg/xtensa/test_break.S b/tests/tcg/xtensa/test_break.S new file mode 100644 index 00000000..775cd7c2 --- /dev/null +++ b/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/tests/tcg/xtensa/test_bz.S b/tests/tcg/xtensa/test_bz.S new file mode 100644 index 00000000..b6813501 --- /dev/null +++ b/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/tests/tcg/xtensa/test_cache.S b/tests/tcg/xtensa/test_cache.S new file mode 100644 index 00000000..6b2df973 --- /dev/null +++ b/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/tests/tcg/xtensa/test_clamps.S b/tests/tcg/xtensa/test_clamps.S new file mode 100644 index 00000000..3efabfd9 --- /dev/null +++ b/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/tests/tcg/xtensa/test_extui.S b/tests/tcg/xtensa/test_extui.S new file mode 100644 index 00000000..c32bb824 --- /dev/null +++ b/tests/tcg/xtensa/test_extui.S @@ -0,0 +1,26 @@ +#include "macros.inc" + +test_suite extui + +.macro test_extui v, shiftimm, maskimm +    .if     \shiftimm + \maskimm <= 32 +    movi    a2, \v +    extui   a3, a2, \shiftimm, \maskimm +    movi    a4, ((\v) >> (\shiftimm)) & ((1 << (\maskimm)) - 1) +    assert  eq, a3, a4 +    .endif +.endm + +test extui +    .set    shiftimm, 0 +    .rept   32 +    .set    maskimm, 1 +    .rept   16 +    test_extui 0xc8df1370, shiftimm, maskimm +    .set    maskimm, maskimm + 1 +    .endr +    .set    shiftimm, shiftimm + 1 +    .endr +test_end + +test_suite_end diff --git a/tests/tcg/xtensa/test_fail.S b/tests/tcg/xtensa/test_fail.S new file mode 100644 index 00000000..1c26d507 --- /dev/null +++ b/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/tests/tcg/xtensa/test_interrupt.S b/tests/tcg/xtensa/test_interrupt.S new file mode 100644 index 00000000..334ddab2 --- /dev/null +++ b/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/tests/tcg/xtensa/test_loop.S b/tests/tcg/xtensa/test_loop.S new file mode 100644 index 00000000..5755578d --- /dev/null +++ b/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/tests/tcg/xtensa/test_mac16.S b/tests/tcg/xtensa/test_mac16.S new file mode 100644 index 00000000..512025d8 --- /dev/null +++ b/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/tests/tcg/xtensa/test_max.S b/tests/tcg/xtensa/test_max.S new file mode 100644 index 00000000..3caa207e --- /dev/null +++ b/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/tests/tcg/xtensa/test_min.S b/tests/tcg/xtensa/test_min.S new file mode 100644 index 00000000..551cf591 --- /dev/null +++ b/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/tests/tcg/xtensa/test_mmu.S b/tests/tcg/xtensa/test_mmu.S new file mode 100644 index 00000000..a15316ff --- /dev/null +++ b/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/tests/tcg/xtensa/test_mul16.S b/tests/tcg/xtensa/test_mul16.S new file mode 100644 index 00000000..98fa7042 --- /dev/null +++ b/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/tests/tcg/xtensa/test_mul32.S b/tests/tcg/xtensa/test_mul32.S new file mode 100644 index 00000000..b288ead9 --- /dev/null +++ b/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/tests/tcg/xtensa/test_nsa.S b/tests/tcg/xtensa/test_nsa.S new file mode 100644 index 00000000..479b2e24 --- /dev/null +++ b/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/tests/tcg/xtensa/test_pipeline.S b/tests/tcg/xtensa/test_pipeline.S new file mode 100644 index 00000000..f418c119 --- /dev/null +++ b/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/tests/tcg/xtensa/test_quo.S b/tests/tcg/xtensa/test_quo.S new file mode 100644 index 00000000..5b3ae383 --- /dev/null +++ b/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/tests/tcg/xtensa/test_rem.S b/tests/tcg/xtensa/test_rem.S new file mode 100644 index 00000000..6357e520 --- /dev/null +++ b/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/tests/tcg/xtensa/test_rst0.S b/tests/tcg/xtensa/test_rst0.S new file mode 100644 index 00000000..a73366b1 --- /dev/null +++ b/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/tests/tcg/xtensa/test_s32c1i.S b/tests/tcg/xtensa/test_s32c1i.S new file mode 100644 index 00000000..93b575db --- /dev/null +++ b/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/tests/tcg/xtensa/test_sar.S b/tests/tcg/xtensa/test_sar.S new file mode 100644 index 00000000..b615a557 --- /dev/null +++ b/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/tests/tcg/xtensa/test_sext.S b/tests/tcg/xtensa/test_sext.S new file mode 100644 index 00000000..087a6333 --- /dev/null +++ b/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/tests/tcg/xtensa/test_shift.S b/tests/tcg/xtensa/test_shift.S new file mode 100644 index 00000000..5df9ed4b --- /dev/null +++ b/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/tests/tcg/xtensa/test_sr.S b/tests/tcg/xtensa/test_sr.S new file mode 100644 index 00000000..4fac46e8 --- /dev/null +++ b/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/tests/tcg/xtensa/test_timer.S b/tests/tcg/xtensa/test_timer.S new file mode 100644 index 00000000..f8c6f742 --- /dev/null +++ b/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/tests/tcg/xtensa/test_windowed.S b/tests/tcg/xtensa/test_windowed.S new file mode 100644 index 00000000..d851e8f4 --- /dev/null +++ b/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/tests/tcg/xtensa/vectors.S b/tests/tcg/xtensa/vectors.S new file mode 100644 index 00000000..265a1812 --- /dev/null +++ b/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  | 
