diff options
author | Andreas Färber | 2013-01-10 21:52:28 +0100 |
---|---|---|
committer | Andreas Färber | 2013-01-10 21:52:28 +0100 |
commit | 63e3555e80c31776285accbb4d0c14ae91c457dc (patch) | |
tree | 89907c82724d6519c8bbad7acc15c0198c6f902f /tests | |
parent | prep: Use pc87312 device instead of collection of random ISA devices (diff) | |
parent | Merge remote-tracking branch 'kraxel/build.1' into staging (diff) | |
download | qemu-63e3555e80c31776285accbb4d0c14ae91c457dc.tar.gz qemu-63e3555e80c31776285accbb4d0c14ae91c457dc.tar.xz qemu-63e3555e80c31776285accbb4d0c14ae91c457dc.zip |
Merge branch 'master' of git://git.qemu.org/qemu into prep-up
Conflicts:
hw/Makefile.objs
hw/ppc_prep.c
Signed-off-by: Andreas Färber <andreas.faerber@web.de>
Diffstat (limited to 'tests')
544 files changed, 23641 insertions, 99 deletions
diff --git a/tests/Makefile b/tests/Makefile index 26a67ce6f5..b09a3437cd 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,31 +1,65 @@ export SRC_PATH check-unit-y = tests/check-qdict$(EXESUF) +gcov-files-check-qdict-y = qdict.c check-unit-y += tests/check-qfloat$(EXESUF) +gcov-files-check-qfloat-y = qfloat.c check-unit-y += tests/check-qint$(EXESUF) +gcov-files-check-qint-y = qint.c check-unit-y += tests/check-qstring$(EXESUF) +gcov-files-check-qstring-y = qstring.c check-unit-y += tests/check-qlist$(EXESUF) +gcov-files-check-qlist-y = qlist.c check-unit-y += tests/check-qjson$(EXESUF) +gcov-files-check-qjson-y = qjson.c check-unit-y += tests/test-qmp-output-visitor$(EXESUF) +gcov-files-test-qmp-output-visitor-y = qapi/qmp-output-visitor.c check-unit-y += tests/test-qmp-input-visitor$(EXESUF) +gcov-files-test-qmp-input-visitor-y = qapi/qmp-input-visitor.c check-unit-y += tests/test-qmp-input-strict$(EXESUF) check-unit-y += tests/test-qmp-commands$(EXESUF) +gcov-files-test-qmp-commands-y = qapi/qmp-dispatch.c check-unit-y += tests/test-string-input-visitor$(EXESUF) +gcov-files-test-string-input-visitor-y = qapi/string-input-visitor.c check-unit-y += tests/test-string-output-visitor$(EXESUF) +gcov-files-test-string-output-visitor-y = qapi/string-output-visitor.c check-unit-y += tests/test-coroutine$(EXESUF) +ifeq ($(CONFIG_WIN32),y) +gcov-files-test-coroutine-y = coroutine-win32.c +else +ifeq ($(CONFIG_UCONTEXT_COROUTINE),y) +gcov-files-test-coroutine-y = coroutine-ucontext.c +else +ifeq ($(CONFIG_SIGALTSTACK_COROUTINE),y) +gcov-files-test-coroutine-y = coroutine-sigaltstack.c +else +gcov-files-test-coroutine-y = coroutine-gthread.c +endif +endif +endif check-unit-y += tests/test-visitor-serialization$(EXESUF) check-unit-y += tests/test-iov$(EXESUF) +gcov-files-test-iov-y = iov.c +check-unit-y += tests/test-aio$(EXESUF) +gcov-files-test-aio-$(CONFIG_WIN32) = aio-win32.c +gcov-files-test-aio-$(CONFIG_POSIX) = aio-posix.c +check-unit-y += tests/test-thread-pool$(EXESUF) +gcov-files-test-thread-pool-y = thread-pool.c check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh # All QTests for now are POSIX-only, but the dependencies are # really in libqtest, not in the testcases themselves. check-qtest-i386-y = tests/fdc-test$(EXESUF) +gcov-files-i386-y = hw/fdc.c check-qtest-i386-y += tests/hd-geo-test$(EXESUF) +gcov-files-i386-y += hw/hd-geometry.c check-qtest-i386-y += tests/rtc-test$(EXESUF) check-qtest-x86_64-y = $(check-qtest-i386-y) +gcov-files-i386-y += i386-softmmu/hw/mc146818rtc.c check-qtest-sparc-y = tests/m48t59-test$(EXESUF) check-qtest-sparc64-y = tests/m48t59-test$(EXESUF) +gcov-files-sparc-y += hw/m48t59.c GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h @@ -36,19 +70,21 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \ tests/test-qmp-commands.o tests/test-visitor-serialization.o -test-qapi-obj-y = $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) +test-qapi-obj-y = $(qobject-obj-y) $(qapi-obj-y) qemu-tool.o test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o test-qapi-obj-y += module.o $(test-obj-y): QEMU_INCLUDES += -Itests -tests/check-qint$(EXESUF): tests/check-qint.o qint.o $(tools-obj-y) -tests/check-qstring$(EXESUF): tests/check-qstring.o qstring.o $(tools-obj-y) -tests/check-qdict$(EXESUF): tests/check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(tools-obj-y) -tests/check-qlist$(EXESUF): tests/check-qlist.o qlist.o qint.o $(tools-obj-y) -tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o $(tools-obj-y) -tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) $(tools-obj-y) -tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y) +tests/check-qint$(EXESUF): tests/check-qint.o qint.o +tests/check-qstring$(EXESUF): tests/check-qstring.o qstring.o +tests/check-qdict$(EXESUF): tests/check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o +tests/check-qlist$(EXESUF): tests/check-qlist.o qlist.o qint.o +tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o +tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) qemu-tool.o +tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) iov.o libqemustub.a +tests/test-aio$(EXESUF): tests/test-aio.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) libqemustub.a +tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) libqemustub.a tests/test-iov$(EXESUF): tests/test-iov.o iov.o tests/test-qapi-types.c tests/test-qapi-types.h :\ @@ -81,7 +117,7 @@ TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGET_DIRS))) QTEST_TARGETS=$(foreach TARGET,$(TARGETS), $(if $(check-qtest-$(TARGET)-y), $(TARGET),)) check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y)) -qtest-obj-y = tests/libqtest.o $(oslib-obj-y) $(tools-obj-y) +qtest-obj-y = tests/libqtest.o $(oslib-obj-y) libqemustub.a $(check-qtest-y): $(qtest-obj-y) .PHONY: check-help @@ -104,17 +140,28 @@ check-help: SPEED = quick GTESTER_OPTIONS = -k $(if $(V),--verbose,-q) +GCOV_OPTIONS = -n $(if $(V),-f,) # gtester tests, possibly with verbose output .PHONY: $(patsubst %, check-qtest-%, $(QTEST_TARGETS)) $(patsubst %, check-qtest-%, $(QTEST_TARGETS)): check-qtest-%: $(check-qtest-y) + $(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,) $(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \ gtester $(GTESTER_OPTIONS) -m=$(SPEED) $(check-qtest-$*-y),"GTESTER $@") + $(if $(CONFIG_GCOV),@for f in $(gcov-files-$*-y); do \ + echo Gcov report for $$f:;\ + $(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \ + done,) .PHONY: $(patsubst %, check-%, $(check-unit-y)) $(patsubst %, check-%, $(check-unit-y)): check-%: % + $(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,) $(call quiet-command,gtester $(GTESTER_OPTIONS) -m=$(SPEED) $*,"GTESTER $*") + $(if $(CONFIG_GCOV),@for f in $(gcov-files-$(subst tests/,,$*)-y); do \ + echo Gcov report for $$f:;\ + $(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \ + done,) # gtester tests with XML output diff --git a/tests/check-qdict.c b/tests/check-qdict.c index fc0d276538..dc5f05a85f 100644 --- a/tests/check-qdict.c +++ b/tests/check-qdict.c @@ -11,9 +11,9 @@ */ #include <glib.h> -#include "qint.h" -#include "qdict.h" -#include "qstring.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qstring.h" #include "qemu-common.h" /* diff --git a/tests/check-qfloat.c b/tests/check-qfloat.c index cdc66ea10b..6404ac8df6 100644 --- a/tests/check-qfloat.c +++ b/tests/check-qfloat.c @@ -12,7 +12,7 @@ */ #include <glib.h> -#include "qfloat.h" +#include "qapi/qmp/qfloat.h" #include "qemu-common.h" /* diff --git a/tests/check-qint.c b/tests/check-qint.c index 5a27119ae2..86868844ab 100644 --- a/tests/check-qint.c +++ b/tests/check-qint.c @@ -11,7 +11,7 @@ */ #include <glib.h> -#include "qint.h" +#include "qapi/qmp/qint.h" #include "qemu-common.h" /* diff --git a/tests/check-qjson.c b/tests/check-qjson.c index 526e25ef6d..32ffb436df 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -10,13 +10,13 @@ */ #include <glib.h> -#include "qstring.h" -#include "qint.h" -#include "qdict.h" -#include "qlist.h" -#include "qfloat.h" -#include "qbool.h" -#include "qjson.h" +#include "qapi/qmp/qstring.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qlist.h" +#include "qapi/qmp/qfloat.h" +#include "qapi/qmp/qbool.h" +#include "qapi/qmp/qjson.h" #include "qemu-common.h" @@ -466,6 +466,58 @@ static void simple_dict(void) } } +/* + * this generates json of the form: + * a(0,m) = [0, 1, ..., m-1] + * a(n,m) = { + * 'key0': a(0,m), + * 'key1': a(1,m), + * ... + * 'key(n-1)': a(n-1,m) + * } + */ +static void gen_test_json(GString *gstr, int nest_level_max, + int elem_count) +{ + int i; + + g_assert(gstr); + if (nest_level_max == 0) { + g_string_append(gstr, "["); + for (i = 0; i < elem_count; i++) { + g_string_append_printf(gstr, "%d", i); + if (i < elem_count - 1) { + g_string_append_printf(gstr, ", "); + } + } + g_string_append(gstr, "]"); + return; + } + + g_string_append(gstr, "{"); + for (i = 0; i < nest_level_max; i++) { + g_string_append_printf(gstr, "'key%d': ", i); + gen_test_json(gstr, i, elem_count); + if (i < nest_level_max - 1) { + g_string_append(gstr, ","); + } + } + g_string_append(gstr, "}"); +} + +static void large_dict(void) +{ + GString *gstr = g_string_new(""); + QObject *obj; + + gen_test_json(gstr, 10, 100); + obj = qobject_from_json(gstr->str); + g_assert(obj != NULL); + + qobject_decref(obj); + g_string_free(gstr, true); +} + static void simple_list(void) { int i; @@ -706,6 +758,7 @@ int main(int argc, char **argv) g_test_add_func("/literals/keyword", keyword_literal); g_test_add_func("/dicts/simple_dict", simple_dict); + g_test_add_func("/dicts/large_dict", large_dict); g_test_add_func("/lists/simple_list", simple_list); g_test_add_func("/whitespace/simple_whitespace", simple_whitespace); diff --git a/tests/check-qlist.c b/tests/check-qlist.c index 501ba262da..b9c05d43fd 100644 --- a/tests/check-qlist.c +++ b/tests/check-qlist.c @@ -11,8 +11,8 @@ */ #include <glib.h> -#include "qint.h" -#include "qlist.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qlist.h" /* * Public Interface test-cases diff --git a/tests/check-qstring.c b/tests/check-qstring.c index addad6c673..95dc9e3e7b 100644 --- a/tests/check-qstring.c +++ b/tests/check-qstring.c @@ -11,7 +11,7 @@ */ #include <glib.h> -#include "qstring.h" +#include "qapi/qmp/qstring.h" #include "qemu-common.h" /* diff --git a/tests/fdc-test.c b/tests/fdc-test.c index fa7441110d..4b0301da46 100644 --- a/tests/fdc-test.c +++ b/tests/fdc-test.c @@ -48,13 +48,17 @@ enum { enum { CMD_SENSE_INT = 0x08, + CMD_READ_ID = 0x0a, CMD_SEEK = 0x0f, + CMD_VERIFY = 0x16, CMD_READ = 0xe6, CMD_RELATIVE_SEEK_OUT = 0x8f, CMD_RELATIVE_SEEK_IN = 0xcf, }; enum { + BUSY = 0x10, + NONDMA = 0x20, RQM = 0x80, DIO = 0x40, @@ -110,7 +114,7 @@ static void ack_irq(uint8_t *pcn) g_assert(!get_irq(FLOPPY_IRQ)); } -static uint8_t send_read_command(void) +static uint8_t send_read_command(uint8_t cmd) { uint8_t drive = 0; uint8_t head = 0; @@ -126,7 +130,7 @@ static uint8_t send_read_command(void) uint8_t ret = 0; - floppy_send(CMD_READ); + floppy_send(cmd); floppy_send(head << 2 | drive); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(cyl); @@ -152,7 +156,70 @@ static uint8_t send_read_command(void) } st0 = floppy_recv(); - if (st0 != 0x60) { + if (st0 != 0x40) { + ret = 1; + } + + floppy_recv(); + floppy_recv(); + floppy_recv(); + floppy_recv(); + floppy_recv(); + floppy_recv(); + + return ret; +} + +static uint8_t send_read_no_dma_command(int nb_sect, uint8_t expected_st0) +{ + uint8_t drive = 0; + uint8_t head = 0; + uint8_t cyl = 0; + uint8_t sect_addr = 1; + uint8_t sect_size = 2; + uint8_t eot = nb_sect; + uint8_t gap = 0x1b; + uint8_t gpl = 0xff; + + uint8_t msr = 0; + uint8_t st0; + + uint8_t ret = 0; + + floppy_send(CMD_READ); + floppy_send(head << 2 | drive); + g_assert(!get_irq(FLOPPY_IRQ)); + floppy_send(cyl); + floppy_send(head); + floppy_send(sect_addr); + floppy_send(sect_size); + floppy_send(eot); + floppy_send(gap); + floppy_send(gpl); + + uint16_t i = 0; + uint8_t n = 2; + for (; i < n; i++) { + msr = inb(FLOPPY_BASE + reg_msr); + if (msr == (BUSY | NONDMA | DIO | RQM)) { + break; + } + sleep(1); + } + + if (i >= n) { + return 1; + } + + /* Non-DMA mode */ + for (i = 0; i < 512 * 2 * nb_sect; i++) { + msr = inb(FLOPPY_BASE + reg_msr); + assert_bit_set(msr, BUSY | RQM | DIO); + inb(FLOPPY_BASE + reg_fifo); + } + + st0 = floppy_recv(); + if (st0 != expected_st0) { ret = 1; } @@ -213,11 +280,11 @@ static void test_read_without_media(void) { uint8_t ret; - ret = send_read_command(); + ret = send_read_command(CMD_READ); g_assert(ret == 0); } -static void test_media_change(void) +static void test_media_insert(void) { uint8_t dir; @@ -245,6 +312,13 @@ static void test_media_change(void) assert_bit_clear(dir, DSKCHG); dir = inb(FLOPPY_BASE + reg_dir); assert_bit_clear(dir, DSKCHG); +} + +static void test_media_change(void) +{ + uint8_t dir; + + test_media_insert(); /* Eject the floppy and check that DSKCHG is set. Reading it out doesn't * reset the bit. */ @@ -320,6 +394,108 @@ static void test_relative_seek(void) g_assert(pcn == 0); } +static void test_read_id(void) +{ + uint8_t drive = 0; + uint8_t head = 0; + uint8_t cyl; + uint8_t st0; + + /* Seek to track 0 and check with READ ID */ + send_seek(0); + + floppy_send(CMD_READ_ID); + g_assert(!get_irq(FLOPPY_IRQ)); + floppy_send(head << 2 | drive); + + while (!get_irq(FLOPPY_IRQ)) { + /* qemu involves a timer with READ ID... */ + clock_step(1000000000LL / 50); + } + + st0 = floppy_recv(); + floppy_recv(); + floppy_recv(); + cyl = floppy_recv(); + head = floppy_recv(); + floppy_recv(); + floppy_recv(); + + g_assert_cmpint(cyl, ==, 0); + g_assert_cmpint(head, ==, 0); + g_assert_cmpint(st0, ==, head << 2); + + /* Seek to track 8 on head 1 and check with READ ID */ + head = 1; + cyl = 8; + + floppy_send(CMD_SEEK); + floppy_send(head << 2 | drive); + g_assert(!get_irq(FLOPPY_IRQ)); + floppy_send(cyl); + g_assert(get_irq(FLOPPY_IRQ)); + ack_irq(NULL); + + floppy_send(CMD_READ_ID); + g_assert(!get_irq(FLOPPY_IRQ)); + floppy_send(head << 2 | drive); + + while (!get_irq(FLOPPY_IRQ)) { + /* qemu involves a timer with READ ID... */ + clock_step(1000000000LL / 50); + } + + st0 = floppy_recv(); + floppy_recv(); + floppy_recv(); + cyl = floppy_recv(); + head = floppy_recv(); + floppy_recv(); + floppy_recv(); + + g_assert_cmpint(cyl, ==, 8); + g_assert_cmpint(head, ==, 1); + g_assert_cmpint(st0, ==, head << 2); +} + +static void test_read_no_dma_1(void) +{ + uint8_t ret; + + outb(FLOPPY_BASE + reg_dor, inb(FLOPPY_BASE + reg_dor) & ~0x08); + send_seek(0); + ret = send_read_no_dma_command(1, 0x04); + g_assert(ret == 0); +} + +static void test_read_no_dma_18(void) +{ + uint8_t ret; + + outb(FLOPPY_BASE + reg_dor, inb(FLOPPY_BASE + reg_dor) & ~0x08); + send_seek(0); + ret = send_read_no_dma_command(18, 0x04); + g_assert(ret == 0); +} + +static void test_read_no_dma_19(void) +{ + uint8_t ret; + + outb(FLOPPY_BASE + reg_dor, inb(FLOPPY_BASE + reg_dor) & ~0x08); + send_seek(0); + ret = send_read_no_dma_command(19, 0x20); + g_assert(ret == 0); +} + +static void test_verify(void) +{ + uint8_t ret; + + ret = send_read_command(CMD_VERIFY); + g_assert(ret == 0); +} + /* success if no crash or abort */ static void fuzz_registers(void) { @@ -369,6 +545,12 @@ int main(int argc, char **argv) qtest_add_func("/fdc/media_change", test_media_change); qtest_add_func("/fdc/sense_interrupt", test_sense_interrupt); qtest_add_func("/fdc/relative_seek", test_relative_seek); + qtest_add_func("/fdc/read_id", test_read_id); + qtest_add_func("/fdc/verify", test_verify); + qtest_add_func("/fdc/media_insert", test_media_insert); + qtest_add_func("/fdc/read_no_dma_1", test_read_no_dma_1); + qtest_add_func("/fdc/read_no_dma_18", test_read_no_dma_18); + qtest_add_func("/fdc/read_no_dma_19", test_read_no_dma_19); qtest_add_func("/fdc/fuzz-registers", fuzz_registers); ret = g_test_run(); diff --git a/tests/libqtest.c b/tests/libqtest.c index 02d039218d..913fa0535c 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -26,8 +26,8 @@ #include <unistd.h> #include <string.h> -#include "compiler.h" -#include "osdep.h" +#include "qemu/compiler.h" +#include "qemu/osdep.h" #define MAX_IRQ 256 @@ -85,6 +85,22 @@ static int socket_accept(int sock) return ret; } +static pid_t qtest_qemu_pid(QTestState *s) +{ + FILE *f; + char buffer[1024]; + pid_t pid = -1; + + f = fopen(s->pid_file, "r"); + if (f) { + if (fgets(buffer, sizeof(buffer), f)) { + pid = atoi(buffer); + } + } + fclose(f); + return pid; +} + QTestState *qtest_init(const char *extra_args) { QTestState *s; @@ -136,25 +152,21 @@ QTestState *qtest_init(const char *extra_args) qtest_qmp(s, ""); qtest_qmp(s, "{ 'execute': 'qmp_capabilities' }"); + if (getenv("QTEST_STOP")) { + kill(qtest_qemu_pid(s), SIGSTOP); + } + return s; } void qtest_quit(QTestState *s) { - FILE *f; - char buffer[1024]; - - f = fopen(s->pid_file, "r"); - if (f) { - if (fgets(buffer, sizeof(buffer), f)) { - pid_t pid = atoi(buffer); - int status = 0; - - kill(pid, SIGTERM); - waitpid(pid, &status, 0); - } + int status; - fclose(f); + pid_t pid = qtest_qemu_pid(s); + if (pid != -1) { + kill(pid, SIGTERM); + waitpid(pid, &status, 0); } unlink(s->pid_file); diff --git a/tests/m48t59-test.c b/tests/m48t59-test.c index 5179681ca5..d79f55472d 100644 --- a/tests/m48t59-test.c +++ b/tests/m48t59-test.c @@ -233,6 +233,11 @@ static void fuzz_registers(void) reg = (uint8_t)g_test_rand_int_range(0, 16); val = (uint8_t)g_test_rand_int_range(0, 256); + if (reg == 7) { + /* watchdog setup register, may trigger system reset, skip */ + continue; + } + cmos_write(reg, val); cmos_read(reg); } diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index f71ab8dd10..dd4ef11996 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -18,6 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # +import time import os import iotests from iotests import qemu_img, qemu_io @@ -98,6 +99,43 @@ class TestSingleDrive(ImageStreamingTestCase): qemu_io('-c', 'map', test_img), 'image file map does not match backing file after streaming') + def test_stream_pause(self): + self.assert_no_active_streams() + + result = self.vm.qmp('block-stream', device='drive0') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('block-job-pause', device='drive0') + self.assert_qmp(result, 'return', {}) + + time.sleep(1) + result = self.vm.qmp('query-block-jobs') + offset = self.dictpath(result, 'return[0]/offset') + + time.sleep(1) + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/offset', offset) + + result = self.vm.qmp('block-job-resume', device='drive0') + self.assert_qmp(result, 'return', {}) + + completed = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_COMPLETED': + self.assert_qmp(event, 'data/type', 'stream') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/offset', self.image_len) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_streams() + self.vm.shutdown() + + self.assertEqual(qemu_io('-c', 'map', backing_img), + qemu_io('-c', 'map', test_img), + 'image file map does not match backing file after streaming') + def test_stream_partial(self): self.assert_no_active_streams() @@ -125,6 +163,259 @@ class TestSingleDrive(ImageStreamingTestCase): result = self.vm.qmp('block-stream', device='nonexistent') self.assert_qmp(result, 'error/class', 'DeviceNotFound') + +class TestSmallerBackingFile(ImageStreamingTestCase): + backing_len = 1 * 1024 * 1024 # MB + image_len = 2 * backing_len + + def setUp(self): + self.create_image(backing_img, self.backing_len) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img, str(self.image_len)) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + # If this hangs, then you are missing a fix to complete streaming when the + # end of the backing file is reached. + def test_stream(self): + self.assert_no_active_streams() + + result = self.vm.qmp('block-stream', device='drive0') + self.assert_qmp(result, 'return', {}) + + completed = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_COMPLETED': + self.assert_qmp(event, 'data/type', 'stream') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/offset', self.image_len) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_streams() + self.vm.shutdown() + +class TestErrors(ImageStreamingTestCase): + image_len = 2 * 1024 * 1024 # MB + + # this should match STREAM_BUFFER_SIZE/512 in block/stream.c + STREAM_BUFFER_SIZE = 512 * 1024 + + def create_blkdebug_file(self, name, event, errno): + file = open(name, 'w') + file.write(''' +[inject-error] +state = "1" +event = "%s" +errno = "%d" +immediately = "off" +once = "on" +sector = "%d" + +[set-state] +state = "1" +event = "%s" +new_state = "2" + +[set-state] +state = "2" +event = "%s" +new_state = "1" +''' % (event, errno, self.STREAM_BUFFER_SIZE / 512, event, event)) + file.close() + +class TestEIO(TestErrors): + def setUp(self): + self.blkdebug_file = backing_img + ".blkdebug" + self.create_image(backing_img, TestErrors.image_len) + self.create_blkdebug_file(self.blkdebug_file, "read_aio", 5) + qemu_img('create', '-f', iotests.imgfmt, + '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw' + % (self.blkdebug_file, backing_img), + test_img) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(backing_img) + os.remove(self.blkdebug_file) + + def test_report(self): + self.assert_no_active_streams() + + result = self.vm.qmp('block-stream', device='drive0') + self.assert_qmp(result, 'return', {}) + + completed = False + error = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_ERROR': + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'read') + error = True + elif event['event'] == 'BLOCK_JOB_COMPLETED': + self.assertTrue(error, 'job completed unexpectedly') + self.assert_qmp(event, 'data/type', 'stream') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/error', 'Input/output error') + self.assert_qmp(event, 'data/offset', self.STREAM_BUFFER_SIZE) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_streams() + self.vm.shutdown() + + def test_ignore(self): + self.assert_no_active_streams() + + result = self.vm.qmp('block-stream', device='drive0', on_error='ignore') + self.assert_qmp(result, 'return', {}) + + error = False + completed = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_ERROR': + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'read') + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', False) + error = True + elif event['event'] == 'BLOCK_JOB_COMPLETED': + self.assertTrue(error, 'job completed unexpectedly') + self.assert_qmp(event, 'data/type', 'stream') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/error', 'Input/output error') + self.assert_qmp(event, 'data/offset', self.image_len) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_streams() + self.vm.shutdown() + + def test_stop(self): + self.assert_no_active_streams() + + result = self.vm.qmp('block-stream', device='drive0', on_error='stop') + self.assert_qmp(result, 'return', {}) + + error = False + completed = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_ERROR': + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'read') + + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', True) + self.assert_qmp(result, 'return[0]/offset', self.STREAM_BUFFER_SIZE) + self.assert_qmp(result, 'return[0]/io-status', 'failed') + + result = self.vm.qmp('block-job-resume', device='drive0') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', False) + self.assert_qmp(result, 'return[0]/io-status', 'ok') + error = True + elif event['event'] == 'BLOCK_JOB_COMPLETED': + self.assertTrue(error, 'job completed unexpectedly') + self.assert_qmp(event, 'data/type', 'stream') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp_absent(event, 'data/error') + self.assert_qmp(event, 'data/offset', self.image_len) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_streams() + self.vm.shutdown() + + def test_enospc(self): + self.assert_no_active_streams() + + result = self.vm.qmp('block-stream', device='drive0', on_error='enospc') + self.assert_qmp(result, 'return', {}) + + completed = False + error = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_ERROR': + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'read') + error = True + elif event['event'] == 'BLOCK_JOB_COMPLETED': + self.assertTrue(error, 'job completed unexpectedly') + self.assert_qmp(event, 'data/type', 'stream') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/error', 'Input/output error') + self.assert_qmp(event, 'data/offset', self.STREAM_BUFFER_SIZE) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_streams() + self.vm.shutdown() + +class TestENOSPC(TestErrors): + def setUp(self): + self.blkdebug_file = backing_img + ".blkdebug" + self.create_image(backing_img, TestErrors.image_len) + self.create_blkdebug_file(self.blkdebug_file, "read_aio", 28) + qemu_img('create', '-f', iotests.imgfmt, + '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw' + % (self.blkdebug_file, backing_img), + test_img) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(backing_img) + os.remove(self.blkdebug_file) + + def test_enospc(self): + self.assert_no_active_streams() + + result = self.vm.qmp('block-stream', device='drive0', on_error='enospc') + self.assert_qmp(result, 'return', {}) + + error = False + completed = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_ERROR': + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'read') + + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', True) + self.assert_qmp(result, 'return[0]/offset', self.STREAM_BUFFER_SIZE) + self.assert_qmp(result, 'return[0]/io-status', 'nospace') + + result = self.vm.qmp('block-job-resume', device='drive0') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', False) + self.assert_qmp(result, 'return[0]/io-status', 'ok') + error = True + elif event['event'] == 'BLOCK_JOB_COMPLETED': + self.assertTrue(error, 'job completed unexpectedly') + self.assert_qmp(event, 'data/type', 'stream') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp_absent(event, 'data/error') + self.assert_qmp(event, 'data/offset', self.image_len) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_streams() + self.vm.shutdown() + class TestStreamStop(ImageStreamingTestCase): image_len = 8 * 1024 * 1024 * 1024 # GB @@ -140,8 +431,6 @@ class TestStreamStop(ImageStreamingTestCase): os.remove(backing_img) def test_stream_stop(self): - import time - self.assert_no_active_streams() result = self.vm.qmp('block-stream', device='drive0') diff --git a/tests/qemu-iotests/030.out b/tests/qemu-iotests/030.out index 3f8a935a08..fa16b5ccef 100644 --- a/tests/qemu-iotests/030.out +++ b/tests/qemu-iotests/030.out @@ -1,5 +1,5 @@ -...... +............. ---------------------------------------------------------------------- -Ran 6 tests +Ran 13 tests OK diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040 new file mode 100755 index 0000000000..aad535a74b --- /dev/null +++ b/tests/qemu-iotests/040 @@ -0,0 +1,280 @@ +#!/usr/bin/env python +# +# Tests for image block commit. +# +# Copyright (C) 2012 IBM, Corp. +# Copyright (C) 2012 Red Hat, Inc. +# +# 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/>. +# +# Test for live block commit +# Derived from Image Streaming Test 030 + +import time +import os +import iotests +from iotests import qemu_img, qemu_io +import struct +import errno + +backing_img = os.path.join(iotests.test_dir, 'backing.img') +mid_img = os.path.join(iotests.test_dir, 'mid.img') +test_img = os.path.join(iotests.test_dir, 'test.img') + +class ImageCommitTestCase(iotests.QMPTestCase): + '''Abstract base class for image commit test cases''' + + def assert_no_active_commit(self): + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return', []) + + def cancel_and_wait(self, drive='drive0'): + '''Cancel a block job and wait for it to finish''' + result = self.vm.qmp('block-job-cancel', device=drive) + self.assert_qmp(result, 'return', {}) + + cancelled = False + while not cancelled: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_CANCELLED': + self.assert_qmp(event, 'data/type', 'commit') + self.assert_qmp(event, 'data/device', drive) + cancelled = True + + self.assert_no_active_commit() + + def create_image(self, name, size): + file = open(name, 'w') + i = 0 + while i < size: + sector = struct.pack('>l504xl', i / 512, i / 512) + file.write(sector) + i = i + 512 + file.close() + + +class TestSingleDrive(ImageCommitTestCase): + image_len = 1 * 1024 * 1024 + test_len = 1 * 1024 * 256 + + def setUp(self): + self.create_image(backing_img, TestSingleDrive.image_len) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img) + qemu_io('-c', 'write -P 0xab 0 524288', backing_img) + qemu_io('-c', 'write -P 0xef 524288 524288', mid_img) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(mid_img) + os.remove(backing_img) + + def test_commit(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % mid_img) + self.assert_qmp(result, 'return', {}) + + completed = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_COMPLETED': + self.assert_qmp(event, 'data/type', 'commit') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/offset', self.image_len) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_commit() + self.vm.shutdown() + + self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed")) + self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed")) + + def test_device_not_found(self): + result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img) + self.assert_qmp(result, 'error/class', 'DeviceNotFound') + + def test_top_same_base(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % backing_img, base='%s' % backing_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % backing_img) + + def test_top_invalid(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='badfile', base='%s' % backing_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Top image file badfile not found') + + def test_base_invalid(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % mid_img, base='badfile') + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found') + + def test_top_is_active(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % test_img, base='%s' % backing_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Top image as the active layer is currently unsupported') + + def test_top_and_base_reversed(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % backing_img, base='%s' % mid_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % mid_img) + + def test_top_omitted(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0') + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', "Parameter 'top' is missing") + +class TestRelativePaths(ImageCommitTestCase): + image_len = 1 * 1024 * 1024 + test_len = 1 * 1024 * 256 + + dir1 = "dir1" + dir2 = "dir2/" + dir3 = "dir2/dir3/" + + test_img = os.path.join(iotests.test_dir, dir3, 'test.img') + mid_img = "../mid.img" + backing_img = "../dir1/backing.img" + + backing_img_abs = os.path.join(iotests.test_dir, dir1, 'backing.img') + mid_img_abs = os.path.join(iotests.test_dir, dir2, 'mid.img') + + def setUp(self): + try: + os.mkdir(os.path.join(iotests.test_dir, self.dir1)) + os.mkdir(os.path.join(iotests.test_dir, self.dir2)) + os.mkdir(os.path.join(iotests.test_dir, self.dir3)) + except OSError as exception: + if exception.errno != errno.EEXIST: + raise + self.create_image(self.backing_img_abs, TestRelativePaths.image_len) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img_abs, self.mid_img_abs) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.mid_img_abs, self.test_img) + qemu_img('rebase', '-u', '-b', self.backing_img, self.mid_img_abs) + qemu_img('rebase', '-u', '-b', self.mid_img, self.test_img) + qemu_io('-c', 'write -P 0xab 0 524288', self.backing_img_abs) + qemu_io('-c', 'write -P 0xef 524288 524288', self.mid_img_abs) + self.vm = iotests.VM().add_drive(self.test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(self.test_img) + os.remove(self.mid_img_abs) + os.remove(self.backing_img_abs) + try: + os.rmdir(os.path.join(iotests.test_dir, self.dir1)) + os.rmdir(os.path.join(iotests.test_dir, self.dir3)) + os.rmdir(os.path.join(iotests.test_dir, self.dir2)) + except OSError as exception: + if exception.errno != errno.EEXIST and exception.errno != errno.ENOTEMPTY: + raise + + def test_commit(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img) + self.assert_qmp(result, 'return', {}) + + completed = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_COMPLETED': + self.assert_qmp(event, 'data/type', 'commit') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/offset', self.image_len) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_commit() + self.vm.shutdown() + + self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed")) + self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed")) + + def test_device_not_found(self): + result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % self.mid_img) + self.assert_qmp(result, 'error/class', 'DeviceNotFound') + + def test_top_same_base(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img, base='%s' % self.mid_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % self.mid_img) + + def test_top_invalid(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='badfile', base='%s' % self.backing_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Top image file badfile not found') + + def test_base_invalid(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img, base='badfile') + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found') + + def test_top_is_active(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.test_img, base='%s' % self.backing_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Top image as the active layer is currently unsupported') + + def test_top_and_base_reversed(self): + self.assert_no_active_commit() + result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.backing_img, base='%s' % self.mid_img) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % self.mid_img) + + +class TestSetSpeed(ImageCommitTestCase): + image_len = 80 * 1024 * 1024 # MB + + def setUp(self): + qemu_img('create', backing_img, str(TestSetSpeed.image_len)) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(mid_img) + os.remove(backing_img) + + def test_set_speed(self): + self.assert_no_active_commit() + + result = self.vm.qmp('block-commit', device='drive0', top=mid_img, speed=1024 * 1024) + self.assert_qmp(result, 'return', {}) + + # Ensure the speed we set was accepted + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/device', 'drive0') + self.assert_qmp(result, 'return[0]/speed', 1024 * 1024) + + self.cancel_and_wait() + + +if __name__ == '__main__': + iotests.main(supported_fmts=['qcow2', 'qed']) diff --git a/tests/qemu-iotests/040.out b/tests/qemu-iotests/040.out new file mode 100644 index 0000000000..b6f257674e --- /dev/null +++ b/tests/qemu-iotests/040.out @@ -0,0 +1,5 @@ +................ +---------------------------------------------------------------------- +Ran 16 tests + +OK diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 new file mode 100755 index 0000000000..c6eb851871 --- /dev/null +++ b/tests/qemu-iotests/041 @@ -0,0 +1,615 @@ +#!/usr/bin/env python +# +# Tests for image mirroring. +# +# Copyright (C) 2012 Red Hat, Inc. +# +# 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/>. +# + +import time +import os +import iotests +from iotests import qemu_img, qemu_io +import struct + +backing_img = os.path.join(iotests.test_dir, 'backing.img') +target_backing_img = os.path.join(iotests.test_dir, 'target-backing.img') +test_img = os.path.join(iotests.test_dir, 'test.img') +target_img = os.path.join(iotests.test_dir, 'target.img') + +class ImageMirroringTestCase(iotests.QMPTestCase): + '''Abstract base class for image mirroring test cases''' + + def assert_no_active_mirrors(self): + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return', []) + + def cancel_and_wait(self, drive='drive0', wait_ready=True): + '''Cancel a block job and wait for it to finish''' + if wait_ready: + ready = False + while not ready: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_READY': + self.assert_qmp(event, 'data/type', 'mirror') + self.assert_qmp(event, 'data/device', drive) + ready = True + + result = self.vm.qmp('block-job-cancel', device=drive, + force=not wait_ready) + self.assert_qmp(result, 'return', {}) + + cancelled = False + while not cancelled: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_COMPLETED' or \ + event['event'] == 'BLOCK_JOB_CANCELLED': + self.assert_qmp(event, 'data/type', 'mirror') + self.assert_qmp(event, 'data/device', drive) + if wait_ready: + self.assertEquals(event['event'], 'BLOCK_JOB_COMPLETED') + self.assert_qmp(event, 'data/offset', self.image_len) + self.assert_qmp(event, 'data/len', self.image_len) + cancelled = True + + self.assert_no_active_mirrors() + + def complete_and_wait(self, drive='drive0', wait_ready=True): + '''Complete a block job and wait for it to finish''' + if wait_ready: + ready = False + while not ready: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_READY': + self.assert_qmp(event, 'data/type', 'mirror') + self.assert_qmp(event, 'data/device', drive) + ready = True + + result = self.vm.qmp('block-job-complete', device=drive) + self.assert_qmp(result, 'return', {}) + + completed = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_COMPLETED': + self.assert_qmp(event, 'data/type', 'mirror') + self.assert_qmp(event, 'data/device', drive) + self.assert_qmp_absent(event, 'data/error') + self.assert_qmp(event, 'data/offset', self.image_len) + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_mirrors() + + def create_image(self, name, size): + file = open(name, 'w') + i = 0 + while i < size: + sector = struct.pack('>l504xl', i / 512, i / 512) + file.write(sector) + i = i + 512 + file.close() + + def compare_images(self, img1, img2): + try: + qemu_img('convert', '-f', iotests.imgfmt, '-O', 'raw', img1, img1 + '.raw') + qemu_img('convert', '-f', iotests.imgfmt, '-O', 'raw', img2, img2 + '.raw') + file1 = open(img1 + '.raw', 'r') + file2 = open(img2 + '.raw', 'r') + return file1.read() == file2.read() + finally: + if file1 is not None: + file1.close() + if file2 is not None: + file2.close() + try: + os.remove(img1 + '.raw') + except OSError: + pass + try: + os.remove(img2 + '.raw') + except OSError: + pass + +class TestSingleDrive(ImageMirroringTestCase): + image_len = 1 * 1024 * 1024 # MB + + def setUp(self): + self.create_image(backing_img, TestSingleDrive.image_len) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(backing_img) + try: + os.remove(target_img) + except OSError: + pass + + def test_complete(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img) + self.assert_qmp(result, 'return', {}) + + self.complete_and_wait() + result = self.vm.qmp('query-block') + self.assert_qmp(result, 'return[0]/inserted/file', target_img) + self.vm.shutdown() + self.assertTrue(self.compare_images(test_img, target_img), + 'target image does not match source after mirroring') + + def test_cancel(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img) + self.assert_qmp(result, 'return', {}) + + self.cancel_and_wait(wait_ready=False) + result = self.vm.qmp('query-block') + self.assert_qmp(result, 'return[0]/inserted/file', test_img) + self.vm.shutdown() + + def test_cancel_after_ready(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img) + self.assert_qmp(result, 'return', {}) + + self.cancel_and_wait() + result = self.vm.qmp('query-block') + self.assert_qmp(result, 'return[0]/inserted/file', test_img) + self.vm.shutdown() + self.assertTrue(self.compare_images(test_img, target_img), + 'target image does not match source after mirroring') + + def test_pause(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('block-job-pause', device='drive0') + self.assert_qmp(result, 'return', {}) + + time.sleep(1) + result = self.vm.qmp('query-block-jobs') + offset = self.dictpath(result, 'return[0]/offset') + + time.sleep(1) + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/offset', offset) + + result = self.vm.qmp('block-job-resume', device='drive0') + self.assert_qmp(result, 'return', {}) + + self.complete_and_wait() + self.vm.shutdown() + self.assertTrue(self.compare_images(test_img, target_img), + 'target image does not match source after mirroring') + + def test_large_cluster(self): + self.assert_no_active_mirrors() + + qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s' + % (TestSingleDrive.image_len, backing_img), target_img) + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + mode='existing', target=target_img) + self.assert_qmp(result, 'return', {}) + + self.complete_and_wait() + result = self.vm.qmp('query-block') + self.assert_qmp(result, 'return[0]/inserted/file', target_img) + self.vm.shutdown() + self.assertTrue(self.compare_images(test_img, target_img), + 'target image does not match source after mirroring') + + def test_medium_not_found(self): + result = self.vm.qmp('drive-mirror', device='ide1-cd0', sync='full', + target=target_img) + self.assert_qmp(result, 'error/class', 'GenericError') + + def test_image_not_found(self): + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + mode='existing', target=target_img) + self.assert_qmp(result, 'error/class', 'GenericError') + + def test_device_not_found(self): + result = self.vm.qmp('drive-mirror', device='nonexistent', sync='full', + target=target_img) + self.assert_qmp(result, 'error/class', 'DeviceNotFound') + +class TestMirrorNoBacking(ImageMirroringTestCase): + image_len = 2 * 1024 * 1024 # MB + + def complete_and_wait(self, drive='drive0', wait_ready=True): + self.create_image(target_backing_img, TestMirrorNoBacking.image_len) + return ImageMirroringTestCase.complete_and_wait(self, drive, wait_ready) + + def compare_images(self, img1, img2): + self.create_image(target_backing_img, TestMirrorNoBacking.image_len) + return ImageMirroringTestCase.compare_images(self, img1, img2) + + def setUp(self): + self.create_image(backing_img, TestMirrorNoBacking.image_len) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(backing_img) + os.remove(target_backing_img) + os.remove(target_img) + + def test_complete(self): + self.assert_no_active_mirrors() + + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img) + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + mode='existing', target=target_img) + self.assert_qmp(result, 'return', {}) + + self.complete_and_wait() + result = self.vm.qmp('query-block') + self.assert_qmp(result, 'return[0]/inserted/file', target_img) + self.vm.shutdown() + self.assertTrue(self.compare_images(test_img, target_img), + 'target image does not match source after mirroring') + + def test_cancel(self): + self.assert_no_active_mirrors() + + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img) + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + mode='existing', target=target_img) + self.assert_qmp(result, 'return', {}) + + self.cancel_and_wait() + result = self.vm.qmp('query-block') + self.assert_qmp(result, 'return[0]/inserted/file', test_img) + self.vm.shutdown() + self.assertTrue(self.compare_images(test_img, target_img), + 'target image does not match source after mirroring') + +class TestReadErrors(ImageMirroringTestCase): + image_len = 2 * 1024 * 1024 # MB + + # this should be a multiple of twice the default granularity + # so that we hit this offset first in state 1 + MIRROR_GRANULARITY = 1024 * 1024 + + def create_blkdebug_file(self, name, event, errno): + file = open(name, 'w') + file.write(''' +[inject-error] +state = "1" +event = "%s" +errno = "%d" +immediately = "off" +once = "on" +sector = "%d" + +[set-state] +state = "1" +event = "%s" +new_state = "2" + +[set-state] +state = "2" +event = "%s" +new_state = "1" +''' % (event, errno, self.MIRROR_GRANULARITY / 512, event, event)) + file.close() + + def setUp(self): + self.blkdebug_file = backing_img + ".blkdebug" + self.create_image(backing_img, TestReadErrors.image_len) + self.create_blkdebug_file(self.blkdebug_file, "read_aio", 5) + qemu_img('create', '-f', iotests.imgfmt, + '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw' + % (self.blkdebug_file, backing_img), + test_img) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(backing_img) + os.remove(self.blkdebug_file) + + def test_report_read(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img) + self.assert_qmp(result, 'return', {}) + + completed = False + error = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_ERROR': + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'read') + error = True + elif event['event'] == 'BLOCK_JOB_READY': + self.assertTrue(False, 'job completed unexpectedly') + elif event['event'] == 'BLOCK_JOB_COMPLETED': + self.assertTrue(error, 'job completed unexpectedly') + self.assert_qmp(event, 'data/type', 'mirror') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/error', 'Input/output error') + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_mirrors() + self.vm.shutdown() + + def test_ignore_read(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img, on_source_error='ignore') + self.assert_qmp(result, 'return', {}) + + event = self.vm.get_qmp_event(wait=True) + self.assertEquals(event['event'], 'BLOCK_JOB_ERROR') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'read') + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', False) + self.complete_and_wait() + self.vm.shutdown() + + def test_stop_read(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img, on_source_error='stop') + self.assert_qmp(result, 'return', {}) + + error = False + ready = False + while not ready: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_ERROR': + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'read') + + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', True) + self.assert_qmp(result, 'return[0]/io-status', 'failed') + + result = self.vm.qmp('block-job-resume', device='drive0') + self.assert_qmp(result, 'return', {}) + error = True + elif event['event'] == 'BLOCK_JOB_READY': + self.assertTrue(error, 'job completed unexpectedly') + self.assert_qmp(event, 'data/device', 'drive0') + ready = True + + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', False) + self.assert_qmp(result, 'return[0]/io-status', 'ok') + + self.complete_and_wait(wait_ready=False) + self.assert_no_active_mirrors() + self.vm.shutdown() + +class TestWriteErrors(ImageMirroringTestCase): + image_len = 2 * 1024 * 1024 # MB + + # this should be a multiple of twice the default granularity + # so that we hit this offset first in state 1 + MIRROR_GRANULARITY = 1024 * 1024 + + def create_blkdebug_file(self, name, event, errno): + file = open(name, 'w') + file.write(''' +[inject-error] +state = "1" +event = "%s" +errno = "%d" +immediately = "off" +once = "on" +sector = "%d" + +[set-state] +state = "1" +event = "%s" +new_state = "2" + +[set-state] +state = "2" +event = "%s" +new_state = "1" +''' % (event, errno, self.MIRROR_GRANULARITY / 512, event, event)) + file.close() + + def setUp(self): + self.blkdebug_file = target_img + ".blkdebug" + self.create_image(backing_img, TestWriteErrors.image_len) + self.create_blkdebug_file(self.blkdebug_file, "write_aio", 5) + qemu_img('create', '-f', iotests.imgfmt, '-obacking_file=%s' %(backing_img), test_img) + self.vm = iotests.VM().add_drive(test_img) + self.target_img = 'blkdebug:%s:%s' % (self.blkdebug_file, target_img) + qemu_img('create', '-f', iotests.imgfmt, '-osize=%d' %(TestWriteErrors.image_len), target_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(backing_img) + os.remove(self.blkdebug_file) + + def test_report_write(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + mode='existing', target=self.target_img) + self.assert_qmp(result, 'return', {}) + + completed = False + error = False + while not completed: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_ERROR': + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'write') + error = True + elif event['event'] == 'BLOCK_JOB_READY': + self.assertTrue(False, 'job completed unexpectedly') + elif event['event'] == 'BLOCK_JOB_COMPLETED': + self.assertTrue(error, 'job completed unexpectedly') + self.assert_qmp(event, 'data/type', 'mirror') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/error', 'Input/output error') + self.assert_qmp(event, 'data/len', self.image_len) + completed = True + + self.assert_no_active_mirrors() + self.vm.shutdown() + + def test_ignore_write(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + mode='existing', target=self.target_img, + on_target_error='ignore') + self.assert_qmp(result, 'return', {}) + + event = self.vm.get_qmp_event(wait=True) + self.assertEquals(event['event'], 'BLOCK_JOB_ERROR') + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'write') + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', False) + self.complete_and_wait() + self.vm.shutdown() + + def test_stop_write(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + mode='existing', target=self.target_img, + on_target_error='stop') + self.assert_qmp(result, 'return', {}) + + error = False + ready = False + while not ready: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_ERROR': + self.assert_qmp(event, 'data/device', 'drive0') + self.assert_qmp(event, 'data/operation', 'write') + + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', True) + self.assert_qmp(result, 'return[0]/io-status', 'failed') + + result = self.vm.qmp('block-job-resume', device='drive0') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/paused', False) + self.assert_qmp(result, 'return[0]/io-status', 'ok') + error = True + elif event['event'] == 'BLOCK_JOB_READY': + self.assertTrue(error, 'job completed unexpectedly') + self.assert_qmp(event, 'data/device', 'drive0') + ready = True + + self.complete_and_wait(wait_ready=False) + self.assert_no_active_mirrors() + self.vm.shutdown() + +class TestSetSpeed(ImageMirroringTestCase): + image_len = 80 * 1024 * 1024 # MB + + def setUp(self): + qemu_img('create', backing_img, str(TestSetSpeed.image_len)) + qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(backing_img) + os.remove(target_img) + + def test_set_speed(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img) + self.assert_qmp(result, 'return', {}) + + # Default speed is 0 + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/device', 'drive0') + self.assert_qmp(result, 'return[0]/speed', 0) + + result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024) + self.assert_qmp(result, 'return', {}) + + # Ensure the speed we set was accepted + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/device', 'drive0') + self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024) + + self.cancel_and_wait() + + # Check setting speed in drive-mirror works + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img, speed=4*1024*1024) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('query-block-jobs') + self.assert_qmp(result, 'return[0]/device', 'drive0') + self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024) + + self.cancel_and_wait() + + def test_set_speed_invalid(self): + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img, speed=-1) + self.assert_qmp(result, 'error/class', 'GenericError') + + self.assert_no_active_mirrors() + + result = self.vm.qmp('drive-mirror', device='drive0', sync='full', + target=target_img) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1) + self.assert_qmp(result, 'error/class', 'GenericError') + + self.cancel_and_wait() + +if __name__ == '__main__': + iotests.main(supported_fmts=['qcow2', 'qed']) diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out new file mode 100644 index 0000000000..71009c239f --- /dev/null +++ b/tests/qemu-iotests/041.out @@ -0,0 +1,5 @@ +.................. +---------------------------------------------------------------------- +Ran 18 tests + +OK diff --git a/tests/qemu-iotests/042 b/tests/qemu-iotests/042 new file mode 100755 index 0000000000..c3c3ca8d02 --- /dev/null +++ b/tests/qemu-iotests/042 @@ -0,0 +1,78 @@ +#!/bin/bash +# +# Test qemu-img operation on zero size images +# +# Copyright (C) 2012 Red Hat, Inc. +# +# 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/>. +# + +# creator +owner=kwolf@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt qcow2 qcow qed vmdk +_supported_proto file +_supported_os Linux + +echo +echo "== Creating zero size image ==" + +_make_test_img 0 +_check_test_img + +mv $TEST_IMG $TEST_IMG.orig + +echo +echo "== Converting the image ==" + +$QEMU_IMG convert -O $IMGFMT $TEST_IMG.orig $TEST_IMG +_check_test_img + +echo +echo "== Converting the image, compressed ==" + +if [ "$IMGFMT" == "qcow2" ]; then + $QEMU_IMG convert -c -O $IMGFMT $TEST_IMG.orig $TEST_IMG +fi +_check_test_img + +echo +echo "== Rebasing the image ==" + +$QEMU_IMG rebase -u -b $TEST_IMG.orig $TEST_IMG +$QEMU_IMG rebase -b $TEST_IMG.orig $TEST_IMG +_check_test_img + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 + diff --git a/tests/qemu-iotests/042.out b/tests/qemu-iotests/042.out new file mode 100644 index 0000000000..dc80f4b5b3 --- /dev/null +++ b/tests/qemu-iotests/042.out @@ -0,0 +1,15 @@ +QA output created by 042 + +== Creating zero size image == +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0 +No errors were found on the image. + +== Converting the image == +No errors were found on the image. + +== Converting the image, compressed == +No errors were found on the image. + +== Rebasing the image == +No errors were found on the image. +*** done diff --git a/tests/qemu-iotests/043 b/tests/qemu-iotests/043 new file mode 100755 index 0000000000..3ba08dc94e --- /dev/null +++ b/tests/qemu-iotests/043 @@ -0,0 +1,95 @@ +#!/bin/bash +# +# Test that qemu-img info --backing-chain detects infinite loops +# +# Copyright (C) 2012 Red Hat, Inc. +# +# 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/>. +# + +# creator +owner=stefanha@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img + rm -f $TEST_IMG.[123].base +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +# Any format supporting backing files +_supported_fmt qcow qcow2 vmdk qed +_supported_proto generic +_supported_os Linux + + +size=128M +_make_test_img $size +$QEMU_IMG rebase -u -b $TEST_IMG $TEST_IMG + +echo +echo "== backing file references self ==" +_img_info --backing-chain + +_make_test_img $size +mv $TEST_IMG $TEST_IMG.base +_make_test_img -b $TEST_IMG.base $size +$QEMU_IMG rebase -u -b $TEST_IMG $TEST_IMG.base + +echo +echo "== parent references self ==" +_img_info --backing-chain + +_make_test_img $size +mv $TEST_IMG $TEST_IMG.1.base +_make_test_img -b $TEST_IMG.1.base $size +mv $TEST_IMG $TEST_IMG.2.base +_make_test_img -b $TEST_IMG.2.base $size +mv $TEST_IMG $TEST_IMG.3.base +_make_test_img -b $TEST_IMG.3.base $size +$QEMU_IMG rebase -u -b $TEST_IMG.2.base $TEST_IMG.1.base + +echo +echo "== ancestor references another ancestor ==" +_img_info --backing-chain + +_make_test_img $size +mv $TEST_IMG $TEST_IMG.1.base +_make_test_img -b $TEST_IMG.1.base $size +mv $TEST_IMG $TEST_IMG.2.base +_make_test_img -b $TEST_IMG.2.base $size + +echo +echo "== finite chain of length 3 (human) ==" +_img_info --backing-chain + +echo +echo "== finite chain of length 3 (json) ==" +_img_info --backing-chain --output=json + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/043.out b/tests/qemu-iotests/043.out new file mode 100644 index 0000000000..ad23337db5 --- /dev/null +++ b/tests/qemu-iotests/043.out @@ -0,0 +1,66 @@ +QA output created by 043 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 + +== backing file references self == +qemu-img: Backing file 'TEST_DIR/t.IMGFMT' creates an infinite loop. +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base' + +== parent references self == +qemu-img: Backing file 'TEST_DIR/t.IMGFMT' creates an infinite loop. +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.1.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.2.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.3.base' + +== ancestor references another ancestor == +qemu-img: Backing file 'TEST_DIR/t.IMGFMT.2.base' creates an infinite loop. +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.1.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.2.base' + +== finite chain of length 3 (human) == +image: TEST_DIR/t.IMGFMT +file format: IMGFMT +virtual size: 128M (134217728 bytes) +cluster_size: 65536 +backing file: TEST_DIR/t.IMGFMT.2.base + +image: TEST_DIR/t.IMGFMT.2.base +file format: IMGFMT +virtual size: 128M (134217728 bytes) +cluster_size: 65536 +backing file: TEST_DIR/t.IMGFMT.1.base + +image: TEST_DIR/t.IMGFMT.1.base +file format: IMGFMT +virtual size: 128M (134217728 bytes) +cluster_size: 65536 + +== finite chain of length 3 (json) == +[ + { + "virtual-size": 134217728, + "filename": "TEST_DIR/t.IMGFMT", + "cluster-size": 65536, + "format": "IMGFMT", + "backing-filename": "TEST_DIR/t.IMGFMT.2.base", + "dirty-flag": false + }, + { + "virtual-size": 134217728, + "filename": "TEST_DIR/t.IMGFMT.2.base", + "cluster-size": 65536, + "format": "IMGFMT", + "backing-filename": "TEST_DIR/t.IMGFMT.1.base", + "dirty-flag": false + }, + { + "virtual-size": 134217728, + "filename": "TEST_DIR/t.IMGFMT.1.base", + "cluster-size": 65536, + "format": "IMGFMT", + "dirty-flag": false + } +] +*** done diff --git a/tests/qemu-iotests/044 b/tests/qemu-iotests/044 new file mode 100755 index 0000000000..11ea0f4d35 --- /dev/null +++ b/tests/qemu-iotests/044 @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# +# Tests growing a large refcount table. +# +# Copyright (C) 2012 Red Hat, Inc. +# +# 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/>. +# + +import time +import os +import qcow2 +from qcow2 import QcowHeader +import iotests +from iotests import qemu_img, qemu_img_verbose, qemu_io +import struct +import subprocess + +test_img = os.path.join(iotests.test_dir, 'test.img') + +class TestRefcountTableGrowth(iotests.QMPTestCase): + '''Abstract base class for image mirroring test cases''' + + def preallocate(self, name): + fd = open(name, "r+b") + try: + off_reftable = 512 + off_refblock = off_reftable + (512 * 512) + off_l1 = off_refblock + (512 * 512 * 64) + off_l2 = off_l1 + (512 * 512 * 4 * 8) + off_data = off_l2 + (512 * 512 * 4 * 512) + + # Write a new header + h = QcowHeader(fd) + h.refcount_table_offset = off_reftable + h.refcount_table_clusters = 512 + h.l1_table_offset = off_l1 + h.l1_size = 512 * 512 * 4 + h.update(fd) + + # Write a refcount table + fd.seek(off_reftable) + + for i in xrange(0, h.refcount_table_clusters): + sector = ''.join(struct.pack('>Q', + off_refblock + i * 64 * 512 + j * 512) + for j in xrange(0, 64)) + fd.write(sector) + + # Write the refcount blocks + assert(fd.tell() == off_refblock) + sector = ''.join(struct.pack('>H', 1) for j in xrange(0, 64 * 256)) + for block in xrange(0, h.refcount_table_clusters): + fd.write(sector) + + # Write the L1 table + assert(fd.tell() == off_l1) + assert(off_l2 + 512 * h.l1_size == off_data) + table = ''.join(struct.pack('>Q', (1 << 63) | off_l2 + 512 * j) + for j in xrange(0, h.l1_size)) + fd.write(table) + + # Write the L2 tables + assert(fd.tell() == off_l2) + img_file_size = h.refcount_table_clusters * 64 * 256 * 512 + remaining = img_file_size - off_data + + off = off_data + while remaining > 1024 * 512: + pytable = list((1 << 63) | off + 512 * j + for j in xrange(0, 1024)) + table = struct.pack('>1024Q', *pytable) + fd.write(table) + remaining = remaining - 1024 * 512 + off = off + 1024 * 512 + + table = ''.join(struct.pack('>Q', (1 << 63) | off + 512 * j) + for j in xrange(0, remaining / 512)) + fd.write(table) + + + # Data + fd.truncate(img_file_size) + + + finally: + fd.close() + + + def setUp(self): + qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=512', test_img, '16G') + self.preallocate(test_img) + pass + + + def tearDown(self): + os.remove(test_img) + pass + + def test_grow_refcount_table(self): + qemu_io('-c', 'write 3800M 1M', test_img) + qemu_img_verbose('check' , test_img) + pass + +if __name__ == '__main__': + iotests.main(supported_fmts=['qcow2']) diff --git a/tests/qemu-iotests/044.out b/tests/qemu-iotests/044.out new file mode 100644 index 0000000000..7a4007137d --- /dev/null +++ b/tests/qemu-iotests/044.out @@ -0,0 +1,6 @@ +No errors were found on the image. +. +---------------------------------------------------------------------- +Ran 1 tests + +OK diff --git a/tests/qemu-iotests/045 b/tests/qemu-iotests/045 new file mode 100755 index 0000000000..2b6f1af27a --- /dev/null +++ b/tests/qemu-iotests/045 @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# +# Tests for fdsets. +# +# Copyright (C) 2012 IBM Corp. +# +# 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/>. +# + +import os +import iotests +from iotests import qemu_img + +image0 = os.path.join(iotests.test_dir, 'image0') +image1 = os.path.join(iotests.test_dir, 'image1') +image2 = os.path.join(iotests.test_dir, 'image2') +image3 = os.path.join(iotests.test_dir, 'image3') +image4 = os.path.join(iotests.test_dir, 'image4') + +class TestFdSets(iotests.QMPTestCase): + + def setUp(self): + self.vm = iotests.VM() + qemu_img('create', '-f', iotests.imgfmt, image0, '128K') + qemu_img('create', '-f', iotests.imgfmt, image1, '128K') + qemu_img('create', '-f', iotests.imgfmt, image2, '128K') + qemu_img('create', '-f', iotests.imgfmt, image3, '128K') + qemu_img('create', '-f', iotests.imgfmt, image4, '128K') + self.file0 = open(image0, 'r') + self.file1 = open(image1, 'w+') + self.file2 = open(image2, 'r') + self.file3 = open(image3, 'r') + self.file4 = open(image4, 'r') + self.vm.add_fd(self.file0.fileno(), 1, 'image0:r') + self.vm.add_fd(self.file1.fileno(), 1, 'image1:w+') + self.vm.add_fd(self.file2.fileno(), 0, 'image2:r') + self.vm.add_fd(self.file3.fileno(), 2, 'image3:r') + self.vm.add_fd(self.file4.fileno(), 2, 'image4:r') + self.vm.add_drive("/dev/fdset/1") + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + self.file0.close() + self.file1.close() + self.file2.close() + self.file3.close() + self.file4.close() + os.remove(image0) + os.remove(image1) + os.remove(image2) + os.remove(image3) + os.remove(image4) + + def test_query_fdset(self): + result = self.vm.qmp('query-fdsets') + self.assert_qmp(result, 'return[0]/fdset-id', 2) + self.assert_qmp(result, 'return[1]/fdset-id', 1) + self.assert_qmp(result, 'return[2]/fdset-id', 0) + self.assert_qmp(result, 'return[0]/fds[0]/opaque', 'image3:r') + self.assert_qmp(result, 'return[0]/fds[1]/opaque', 'image4:r') + self.assert_qmp(result, 'return[1]/fds[0]/opaque', 'image0:r') + self.assert_qmp(result, 'return[1]/fds[1]/opaque', 'image1:w+') + self.assert_qmp(result, 'return[2]/fds[0]/opaque', 'image2:r') + self.vm.shutdown() + + def test_remove_fdset(self): + result = self.vm.qmp('remove-fd', fdset_id=2) + self.assert_qmp(result, 'return', {}) + result = self.vm.qmp('query-fdsets') + self.assert_qmp(result, 'return[0]/fdset-id', 1) + self.assert_qmp(result, 'return[1]/fdset-id', 0) + self.assert_qmp(result, 'return[0]/fds[0]/opaque', 'image0:r') + self.assert_qmp(result, 'return[0]/fds[1]/opaque', 'image1:w+') + self.assert_qmp(result, 'return[1]/fds[0]/opaque', 'image2:r') + self.vm.shutdown() + + def test_remove_fd(self): + result = self.vm.qmp('query-fdsets') + fd_image3 = result['return'][0]['fds'][0]['fd'] + result = self.vm.qmp('remove-fd', fdset_id=2, fd=fd_image3) + self.assert_qmp(result, 'return', {}) + result = self.vm.qmp('query-fdsets') + self.assert_qmp(result, 'return[0]/fdset-id', 2) + self.assert_qmp(result, 'return[1]/fdset-id', 1) + self.assert_qmp(result, 'return[2]/fdset-id', 0) + self.assert_qmp(result, 'return[0]/fds[0]/opaque', 'image4:r') + self.assert_qmp(result, 'return[1]/fds[0]/opaque', 'image0:r') + self.assert_qmp(result, 'return[1]/fds[1]/opaque', 'image1:w+') + self.assert_qmp(result, 'return[2]/fds[0]/opaque', 'image2:r') + self.vm.shutdown() + + def test_remove_fd_invalid_fdset(self): + result = self.vm.qmp('query-fdsets') + fd_image3 = result['return'][0]['fds'][0]['fd'] + result = self.vm.qmp('remove-fd', fdset_id=3, fd=fd_image3) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', + 'File descriptor named \'fdset-id:3, fd:%d\' not found' % fd_image3) + self.vm.shutdown() + + def test_remove_fd_invalid_fd(self): + result = self.vm.qmp('query-fdsets') + result = self.vm.qmp('remove-fd', fdset_id=2, fd=999) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', + 'File descriptor named \'fdset-id:2, fd:999\' not found') + self.vm.shutdown() + + def test_add_fd_invalid_fd(self): + result = self.vm.qmp('add-fd', fdset_id=2) + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', + 'No file descriptor supplied via SCM_RIGHTS') + self.vm.shutdown() + +if __name__ == '__main__': + iotests.main(supported_fmts=['raw']) diff --git a/tests/qemu-iotests/045.out b/tests/qemu-iotests/045.out new file mode 100644 index 0000000000..3f8a935a08 --- /dev/null +++ b/tests/qemu-iotests/045.out @@ -0,0 +1,5 @@ +...... +---------------------------------------------------------------------- +Ran 6 tests + +OK diff --git a/tests/qemu-iotests/046 b/tests/qemu-iotests/046 new file mode 100755 index 0000000000..e0176f42df --- /dev/null +++ b/tests/qemu-iotests/046 @@ -0,0 +1,215 @@ +#!/bin/bash +# +# Test concurrent cluster allocations +# +# Copyright (C) 2012 Red Hat, Inc. +# +# 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/>. +# + +# creator +owner=kwolf@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt qcow2 +_supported_proto generic +_supported_os Linux + +CLUSTER_SIZE=64k +size=128M + +echo +echo "== creating backing file for COW tests ==" + +_make_test_img $size + +function backing_io() +{ + local offset=$1 + local sectors=$2 + local op=$3 + local pattern=0 + local cur_sec=0 + + for i in $(seq 0 $((sectors - 1))); do + cur_sec=$((offset / 65536 + i)) + pattern=$(( ( (cur_sec % 128) + (cur_sec / 128)) % 128 )) + + echo "$op -P $pattern $((cur_sec * 64))k 64k" + done +} + +backing_io 0 16 write | $QEMU_IO $TEST_IMG | _filter_qemu_io + +mv $TEST_IMG $TEST_IMG.base + +_make_test_img -b $TEST_IMG.base 6G + +echo +echo "== Some concurrent requests touching the same cluster ==" + +function overlay_io() +{ +# Allocate middle of cluster 1, then write to somewhere before and after it +cat <<EOF +break write_aio A +aio_write -P 10 0x18000 0x2000 +wait_break A + +aio_write -P 11 0x12000 0x2000 +aio_write -P 12 0x1c000 0x2000 + +resume A +aio_flush +EOF + +# Sequential write case: Alloc middle of cluster 2, then write overlapping +# to next cluster +cat <<EOF +break write_aio A +aio_write -P 20 0x28000 0x2000 +wait_break A +aio_write -P 21 0x2a000 0x10000 +resume A +aio_flush +EOF + +# The same with a gap between both requests +cat <<EOF +break write_aio A +aio_write -P 40 0x48000 0x2000 +wait_break A +aio_write -P 41 0x4c000 0x10000 +resume A +aio_flush +EOF + +# Sequential write, but the next cluster is already allocated +cat <<EOF +write -P 70 0x76000 0x8000 +aio_flush +break write_aio A +aio_write -P 60 0x66000 0x2000 +wait_break A +aio_write -P 61 0x6a000 0xe000 +resume A +aio_flush +EOF + +# Sequential write, but the next cluster is already allocated +# and phyiscally in the right position +cat <<EOF +write -P 89 0x80000 0x1000 +write -P 90 0x96000 0x8000 +aio_flush +discard 0x80000 0x10000 +aio_flush +break write_aio A +aio_write -P 80 0x86000 0x2000 +wait_break A +aio_write -P 81 0x8a000 0xe000 +resume A +aio_flush +EOF + +# Sequential write, and the next cluster is compressed +cat <<EOF +write -P 109 0xa0000 0x1000 +write -c -P 110 0xb0000 0x10000 +aio_flush +discard 0xa0000 0x10000 +aio_flush +break write_aio A +aio_write -P 100 0xa6000 0x2000 +wait_break A +aio_write -P 101 0xaa000 0xe000 +resume A +aio_flush +EOF +} + +overlay_io | $QEMU_IO blkdebug::$TEST_IMG | _filter_qemu_io |\ + sed -e 's/bytes at offset [0-9]*/bytes at offset XXX/g' + +echo +echo "== Verify image content ==" + +function verify_io() +{ + echo read -P 0 0 0x10000 + + echo read -P 1 0x10000 0x2000 + echo read -P 11 0x12000 0x2000 + echo read -P 1 0x14000 0x4000 + echo read -P 10 0x18000 0x2000 + echo read -P 1 0x1a000 0x2000 + echo read -P 12 0x1c000 0x2000 + echo read -P 1 0x1e000 0x2000 + + echo read -P 2 0x20000 0x8000 + echo read -P 20 0x28000 0x2000 + echo read -P 21 0x2a000 0x10000 + echo read -P 3 0x3a000 0x6000 + + echo read -P 4 0x40000 0x8000 + echo read -P 40 0x48000 0x2000 + echo read -P 4 0x4a000 0x2000 + echo read -P 41 0x4c000 0x10000 + echo read -P 5 0x5c000 0x4000 + + echo read -P 6 0x60000 0x6000 + echo read -P 60 0x66000 0x2000 + echo read -P 6 0x68000 0x2000 + echo read -P 61 0x6a000 0xe000 + echo read -P 70 0x78000 0x6000 + echo read -P 7 0x7e000 0x2000 + + echo read -P 8 0x80000 0x6000 + echo read -P 80 0x86000 0x2000 + echo read -P 8 0x88000 0x2000 + echo read -P 81 0x8a000 0xe000 + echo read -P 90 0x98000 0x6000 + echo read -P 9 0x9e000 0x2000 + + echo read -P 10 0xa0000 0x6000 + echo read -P 100 0xa6000 0x2000 + echo read -P 10 0xa8000 0x2000 + echo read -P 101 0xaa000 0xe000 + echo read -P 110 0xb8000 0x8000 +} + +verify_io | $QEMU_IO $TEST_IMG | _filter_qemu_io + +_check_test_img + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/046.out b/tests/qemu-iotests/046.out new file mode 100644 index 0000000000..565360fe60 --- /dev/null +++ b/tests/qemu-iotests/046.out @@ -0,0 +1,163 @@ +QA output created by 046 + +== creating backing file for COW tests == +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +qemu-io> wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 65536 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 131072 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 196608 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 262144 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 327680 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 393216 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 458752 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 524288 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 589824 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 655360 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 720896 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 786432 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 851968 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 917504 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset 983040 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' + +== Some concurrent requests touching the same cluster == +qemu-io> qemu-io> qemu-io> blkdebug: Suspended request 'A' +qemu-io> qemu-io> qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A' +qemu-io> wrote 8192/8192 bytes at offset XXX +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 8192/8192 bytes at offset XXX +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 8192/8192 bytes at offset XXX +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> qemu-io> blkdebug: Suspended request 'A' +qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A' +qemu-io> wrote 8192/8192 bytes at offset XXX +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset XXX +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> qemu-io> blkdebug: Suspended request 'A' +qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A' +qemu-io> wrote 8192/8192 bytes at offset XXX +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset XXX +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 32768/32768 bytes at offset XXX +32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> qemu-io> qemu-io> blkdebug: Suspended request 'A' +qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A' +qemu-io> wrote 8192/8192 bytes at offset XXX +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 57344/57344 bytes at offset XXX +56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 4096/4096 bytes at offset XXX +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 32768/32768 bytes at offset XXX +32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> qemu-io> discard 65536/65536 bytes at offset XXX +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> qemu-io> qemu-io> blkdebug: Suspended request 'A' +qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A' +qemu-io> wrote 8192/8192 bytes at offset XXX +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 57344/57344 bytes at offset XXX +56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 4096/4096 bytes at offset XXX +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> wrote 65536/65536 bytes at offset XXX +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> qemu-io> discard 65536/65536 bytes at offset XXX +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> qemu-io> qemu-io> blkdebug: Suspended request 'A' +qemu-io> qemu-io> qemu-io> blkdebug: Resuming request 'A' +qemu-io> wrote 8192/8192 bytes at offset XXX +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 57344/57344 bytes at offset XXX +56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> +== Verify image content == +qemu-io> read 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 65536 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 73728 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 16384/16384 bytes at offset 81920 +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 98304 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 106496 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 114688 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 122880 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 32768/32768 bytes at offset 131072 +32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 163840 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 65536/65536 bytes at offset 172032 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 24576/24576 bytes at offset 237568 +24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 32768/32768 bytes at offset 262144 +32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 294912 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 303104 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 65536/65536 bytes at offset 311296 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 16384/16384 bytes at offset 376832 +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 24576/24576 bytes at offset 393216 +24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 417792 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 425984 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 57344/57344 bytes at offset 434176 +56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 24576/24576 bytes at offset 491520 +24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 516096 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 24576/24576 bytes at offset 524288 +24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 548864 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 557056 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 57344/57344 bytes at offset 565248 +56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 24576/24576 bytes at offset 622592 +24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 647168 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 24576/24576 bytes at offset 655360 +24 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 679936 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 8192/8192 bytes at offset 688128 +8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 57344/57344 bytes at offset 696320 +56 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> read 32768/32768 bytes at offset 753664 +32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> No errors were found on the image. +*** done diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common index 1f6fdf5c56..b3aad89e2c 100644 --- a/tests/qemu-iotests/common +++ b/tests/qemu-iotests/common @@ -136,6 +136,7 @@ check options -vmdk test vmdk -rbd test rbd -sheepdog test sheepdog + -nbd test nbd -xdiff graphical mode diff -nocache use O_DIRECT on backing file -misalign misalign memory allocations @@ -197,12 +198,14 @@ testlist options IMGPROTO=rbd xpand=false ;; - -sheepdog) IMGPROTO=sheepdog xpand=false ;; - + -nbd) + IMGPROTO=nbd + xpand=false + ;; -nocache) QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --nocache" xpand=false @@ -350,7 +353,11 @@ fi [ "$QEMU" = "" ] && _fatal "qemu not found" [ "$QEMU_IMG" = "" ] && _fatal "qemu-img not found" -[ "$QEMU_IO" = "" ] && _fatal "qemu-img not found" +[ "$QEMU_IO" = "" ] && _fatal "qemu-io not found" + +if [ "$IMGPROTO" = "nbd" ] ; then + [ "$QEMU_NBD" = "" ] && _fatal "qemu-nbd not found" +fi if $valgrind; then export REAL_QEMU_IO="$QEMU_IO_PROG" diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config index df082e750c..08a3f100b8 100644 --- a/tests/qemu-iotests/common.config +++ b/tests/qemu-iotests/common.config @@ -90,21 +90,23 @@ export PS_ALL_FLAGS="-ef" if [ -z "$QEMU_PROG" ]; then export QEMU_PROG="`set_prog_path qemu`" fi -[ "$QEMU_PROG" = "" ] && _fatal "qemu not found" if [ -z "$QEMU_IMG_PROG" ]; then export QEMU_IMG_PROG="`set_prog_path qemu-img`" fi -[ "$QEMU_IMG_PROG" = "" ] && _fatal "qemu-img not found" if [ -z "$QEMU_IO_PROG" ]; then export QEMU_IO_PROG="`set_prog_path qemu-io`" fi -[ "$QEMU_IO_PROG" = "" ] && _fatal "qemu-io not found" + +if [ -z "$QEMU_NBD_PROG" ]; then + export QEMU_NBD_PROG="`set_prog_path qemu-nbd`" +fi export QEMU=$QEMU_PROG -export QEMU_IMG=$QEMU_IMG_PROG +export QEMU_IMG=$QEMU_IMG_PROG export QEMU_IO="$QEMU_IO_PROG $QEMU_IO_OPTIONS" +export QEMU_NBD=$QEMU_NBD_PROG [ -f /etc/qemu-iotest.config ] && . /etc/qemu-iotest.config diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index d534e9466d..aef5f52b4f 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -49,6 +49,9 @@ umask 022 if [ "$IMGPROTO" = "file" ]; then TEST_IMG=$TEST_DIR/t.$IMGFMT +elif [ "$IMGPROTO" = "nbd" ]; then + TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT + TEST_IMG="nbd:127.0.0.1:10810" else TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT fi @@ -86,6 +89,13 @@ _make_test_img() local extra_img_options="" local image_size=$* local optstr="" + local img_name="" + + if [ -n "$TEST_IMG_FILE" ]; then + img_name=$TEST_IMG_FILE + else + img_name=$TEST_IMG + fi if [ -n "$IMGOPTS" ]; then optstr=$(_optstr_add "$optstr" "$IMGOPTS") @@ -104,7 +114,7 @@ _make_test_img() fi # XXX(hch): have global image options? - $QEMU_IMG create -f $IMGFMT $extra_img_options $TEST_IMG $image_size | \ + $QEMU_IMG create -f $IMGFMT $extra_img_options $img_name $image_size | \ sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \ -e "s#$TEST_DIR#TEST_DIR#g" \ -e "s#$IMGFMT#IMGFMT#g" \ @@ -115,12 +125,23 @@ _make_test_img() -e "s# compat6=\\(on\\|off\\)##g" \ -e "s# static=\\(on\\|off\\)##g" \ -e "s# lazy_refcounts=\\(on\\|off\\)##g" + + # Start an NBD server on the image file, which is what we'll be talking to + if [ $IMGPROTO = "nbd" ]; then + eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 $TEST_IMG_FILE &" + QEMU_NBD_PID=$! + sleep 1 # FIXME: qemu-nbd needs to be listening before we continue + fi } _cleanup_test_img() { case "$IMGPROTO" in + nbd) + kill $QEMU_NBD_PID + rm -f $TEST_IMG_FILE + ;; file) rm -f $TEST_DIR/t.$IMGFMT rm -f $TEST_DIR/t.$IMGFMT.orig @@ -145,6 +166,16 @@ _check_test_img() sed -e 's/qemu-img\: This image format does not support checks/No errors were found on the image./' } +_img_info() +{ + $QEMU_IMG info "$@" $TEST_IMG 2>&1 | \ + sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \ + -e "s#$TEST_DIR#TEST_DIR#g" \ + -e "s#$IMGFMT#IMGFMT#g" \ + -e "/^disk size:/ D" \ + -e "/actual-size/ D" +} + _get_pids_by_name() { if [ $# -ne 1 ] diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index ebb5ca4b41..a0307de06b 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -36,7 +36,7 @@ 027 rw auto quick 028 rw backing auto 029 rw auto quick -030 rw auto +030 rw auto backing 031 rw auto quick 032 rw auto 033 rw auto @@ -46,3 +46,10 @@ 037 rw auto backing 038 rw auto backing 039 rw auto +040 rw auto +041 rw auto backing +042 rw auto quick +043 rw auto backing +044 rw auto +045 rw auto +046 rw auto aio diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index e05b1d640b..569ca3d804 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -19,6 +19,7 @@ import os import re import subprocess +import string import unittest import sys; sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'QMP')) import qmp @@ -41,6 +42,10 @@ def qemu_img(*args): devnull = open('/dev/null', 'r+') return subprocess.call(qemu_img_args + list(args), stdin=devnull, stdout=devnull) +def qemu_img_verbose(*args): + '''Run qemu-img without suppressing its output and return the exit code''' + return subprocess.call(qemu_img_args + list(args)) + def qemu_io(*args): '''Run qemu-io and return the stdout data''' args = qemu_io_args + list(args) @@ -74,6 +79,18 @@ class VM(object): self._num_drives += 1 return self + def add_fd(self, fd, fdset, opaque, opts=''): + '''Pass a file descriptor to the VM''' + options = ['fd=%d' % fd, + 'set=%d' % fdset, + 'opaque=%s' % opaque] + if opts: + options.append(opts) + + self._args.append('-add-fd') + self._args.append(','.join(options)) + return self + def launch(self): '''Launch the VM and establish a QMP connection''' devnull = open('/dev/null', 'rb') @@ -96,9 +113,18 @@ class VM(object): os.remove(self._qemu_log_path) self._popen = None + underscore_to_dash = string.maketrans('_', '-') def qmp(self, cmd, **args): '''Invoke a QMP command and return the result dict''' - return self._qmp.cmd(cmd, args=args) + qmp_args = dict() + for k in args.keys(): + qmp_args[k.translate(self.underscore_to_dash)] = args[k] + + return self._qmp.cmd(cmd, args=qmp_args) + + def get_qmp_event(self, wait=False): + '''Poll for one queued QMP events and return it''' + return self._qmp.pull_event(wait=wait) def get_qmp_events(self, wait=False): '''Poll for queued QMP events and return a list of dicts''' @@ -132,6 +158,13 @@ class QMPTestCase(unittest.TestCase): self.fail('invalid index "%s" in path "%s" in "%s"' % (idx, path, str(d))) return d + def assert_qmp_absent(self, d, path): + try: + result = self.dictpath(d, path) + except AssertionError: + return + self.fail('path "%s" has value "%s"' % (path, str(result))) + def assert_qmp(self, d, path, value): '''Assert that the value for a specific path in a QMP dict matches''' result = self.dictpath(d, path) @@ -165,4 +198,4 @@ def main(supported_fmts=[]): try: unittest.main(testRunner=MyTestRunner) finally: - sys.stderr.write(re.sub(r'Ran (\d+) test[s] in [\d.]+s', r'Ran \1 tests', output.getvalue())) + sys.stderr.write(re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 tests', output.getvalue())) diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py index 97f37707bc..fecf5b9a59 100755 --- a/tests/qemu-iotests/qcow2.py +++ b/tests/qemu-iotests/qcow2.py @@ -233,8 +233,9 @@ def usage(): for name, handler, num_args, desc in cmds: print " %-20s - %s" % (name, desc) -if len(sys.argv) < 3: - usage() - sys.exit(1) +if __name__ == '__main__': + if len(sys.argv) < 3: + usage() + sys.exit(1) -main(sys.argv[1], sys.argv[2], sys.argv[3:]) + main(sys.argv[1], sys.argv[2], sys.argv[3:]) diff --git a/tests/rtc-test.c b/tests/rtc-test.c index f23ac3a6cf..e7123cafbc 100644 --- a/tests/rtc-test.c +++ b/tests/rtc-test.c @@ -179,6 +179,81 @@ static void check_time(int wiggle) static int wiggle = 2; +static void set_year_20xx(void) +{ + /* Set BCD mode */ + cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & ~REG_B_DM); + cmos_write(RTC_REG_A, 0x76); + cmos_write(RTC_YEAR, 0x11); + cmos_write(RTC_CENTURY, 0x20); + cmos_write(RTC_MONTH, 0x02); + cmos_write(RTC_DAY_OF_MONTH, 0x02); + cmos_write(RTC_HOURS, 0x02); + cmos_write(RTC_MINUTES, 0x04); + cmos_write(RTC_SECONDS, 0x58); + cmos_write(RTC_REG_A, 0x26); + + g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04); + g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58); + g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11); + g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20); + + if (sizeof(time_t) == 4) { + return; + } + + /* Set a date in 2080 to ensure there is no year-2038 overflow. */ + cmos_write(RTC_REG_A, 0x76); + cmos_write(RTC_YEAR, 0x80); + cmos_write(RTC_REG_A, 0x26); + + g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04); + g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58); + g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x80); + g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20); + + cmos_write(RTC_REG_A, 0x76); + cmos_write(RTC_YEAR, 0x11); + cmos_write(RTC_REG_A, 0x26); + + g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04); + g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58); + g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11); + g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20); +} + +static void set_year_1980(void) +{ + /* Set BCD mode */ + cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & ~REG_B_DM); + cmos_write(RTC_REG_A, 0x76); + cmos_write(RTC_YEAR, 0x80); + cmos_write(RTC_CENTURY, 0x19); + cmos_write(RTC_MONTH, 0x02); + cmos_write(RTC_DAY_OF_MONTH, 0x02); + cmos_write(RTC_HOURS, 0x02); + cmos_write(RTC_MINUTES, 0x04); + cmos_write(RTC_SECONDS, 0x58); + cmos_write(RTC_REG_A, 0x26); + + g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04); + g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58); + g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x80); + g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x19); +} + static void bcd_check_time(void) { /* Set BCD mode */ @@ -256,6 +331,45 @@ static void fuzz_registers(void) } } +static void register_b_set_flag(void) +{ + /* Enable binary-coded decimal (BCD) mode and SET flag in Register B*/ + cmos_write(RTC_REG_B, (cmos_read(RTC_REG_B) & ~REG_B_DM) | REG_B_SET); + + cmos_write(RTC_REG_A, 0x76); + cmos_write(RTC_YEAR, 0x11); + cmos_write(RTC_CENTURY, 0x20); + cmos_write(RTC_MONTH, 0x02); + cmos_write(RTC_DAY_OF_MONTH, 0x02); + cmos_write(RTC_HOURS, 0x02); + cmos_write(RTC_MINUTES, 0x04); + cmos_write(RTC_SECONDS, 0x58); + cmos_write(RTC_REG_A, 0x26); + + /* Since SET flag is still enabled, these are equality checks. */ + g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04); + g_assert_cmpint(cmos_read(RTC_SECONDS), ==, 0x58); + g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11); + g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20); + + /* Disable SET flag in Register B */ + cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & ~REG_B_SET); + + g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04); + + /* Since SET flag is disabled, this is an inequality check. + * We (reasonably) assume that no (sexagesimal) overflow occurs. */ + g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58); + g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02); + g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11); + g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20); +} + int main(int argc, char **argv) { QTestState *s = NULL; @@ -269,6 +383,9 @@ int main(int argc, char **argv) qtest_add_func("/rtc/bcd/check-time", bcd_check_time); qtest_add_func("/rtc/dec/check-time", dec_check_time); qtest_add_func("/rtc/alarm-time", alarm_time); + qtest_add_func("/rtc/set-year/20xx", set_year_20xx); + qtest_add_func("/rtc/set-year/1980", set_year_1980); + qtest_add_func("/rtc/register_b_set_flag", register_b_set_flag); qtest_add_func("/rtc/fuzz-registers", fuzz_registers); ret = g_test_run(); diff --git a/tests/tcg/Makefile b/tests/tcg/Makefile index 15e36a208c..24e3154cae 100644 --- a/tests/tcg/Makefile +++ b/tests/tcg/Makefile @@ -1,13 +1,13 @@ --include ../config-host.mak +-include ../../config-host.mak -include $(SRC_PATH)/rules.mak -$(call set-vpath, $(SRC_PATH)/tests) +$(call set-vpath, $(SRC_PATH)/tests/tcg) -QEMU=../i386-linux-user/qemu-i386 -QEMU_X86_64=../x86_64-linux-user/qemu-x86_64 +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.. +QEMU_INCLUDES += -I../.. CFLAGS=-Wall -O2 -g -fno-strict-aliasing #CFLAGS+=-msse2 LDFLAGS= @@ -22,6 +22,7 @@ I386_TESTS=hello-i386 \ testthread \ sha1-i386 \ test-i386 \ + test-i386-fprem \ test-mmap \ # runcom @@ -36,6 +37,7 @@ TESTS += $(I386_TESTS) endif all: $(patsubst %,run-%,$(TESTS)) +test: all # rules to run tests @@ -54,6 +56,11 @@ run-test-i386: test-i386 -$(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 @@ -74,7 +81,10 @@ run-test_path: test_path # rules to compile tests test_path: test_path.o + $(CC_I386) $(LDFLAGS) -o $@ $^ $(LIBS) + test_path.o: test_path.c + $(CC_I386) $(QEMU_INCLUDES) $(GLIB_CFLAGS) $(CFLAGS) -c -o $@ $^ hello-i386: hello-i386.c $(CC_I386) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $< @@ -86,12 +96,15 @@ testthread: testthread.c # 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) $(CFLAGS) $(LDFLAGS) -o $@ \ + $(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) $(CFLAGS) $(LDFLAGS) -o $@ $(<D)/test-i386.c -lm + $(CC_X86_64) $(QEMU_INCLUDES) $(CFLAGS) $(LDFLAGS) -o $@ $(<D)/test-i386.c -lm # generic Linux and CPU test linux-test: linux-test.c diff --git a/tests/tcg/cris/crisutils.h b/tests/tcg/cris/crisutils.h index 29b71cd7b9..3456b9d50d 100644 --- a/tests/tcg/cris/crisutils.h +++ b/tests/tcg/cris/crisutils.h @@ -1,3 +1,6 @@ +#ifndef CRISUTILS_H +#define CRISUTILS_H 1 + static char *tst_cc_loc = NULL; #define cris_tst_cc_init() \ @@ -69,3 +72,5 @@ static inline void cris_tst_cc(const int n, const int z, if (c) cris_tst_cc_c1(); else cris_tst_cc_c0(); asm volatile ("" : : "g" (_err)); } + +#endif diff --git a/tests/tcg/hello-i386.c b/tests/tcg/hello-i386.c index 86afc34fb1..fa00380de2 100644 --- a/tests/tcg/hello-i386.c +++ b/tests/tcg/hello-i386.c @@ -1,6 +1,6 @@ #include <asm/unistd.h> -static inline volatile void exit(int status) +static inline void exit(int status) { int __res; __asm__ volatile ("movl %%ecx,%%ebx\n"\ @@ -17,6 +17,7 @@ static inline int write(int fd, const char * buf, int len) "popl %%ebx\n"\ : "=a" (status) \ : "0" (__NR_write),"S" ((long)(fd)),"c" ((long)(buf)),"d" ((long)(len))); + return status; } void _start(void) diff --git a/tests/tcg/linux-test.c b/tests/tcg/linux-test.c index 2e4a746ac3..83cb32ddb9 100644 --- a/tests/tcg/linux-test.c +++ b/tests/tcg/linux-test.c @@ -16,6 +16,7 @@ * 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> @@ -38,6 +39,7 @@ #include <dirent.h> #include <setjmp.h> #include <sys/shm.h> +#include <sched.h> #define TESTPATH "/tmp/linux-test.tmp" #define TESTPORT 7654 diff --git a/tests/tcg/mips/mips32-dsp/Makefile b/tests/tcg/mips/mips32-dsp/Makefile new file mode 100644 index 0000000000..c3a0a00944 --- /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 0000000000..aa8411202e --- /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 0000000000..3f52a48039 --- /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 0000000000..96a549637b --- /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 0000000000..5f865f6cff --- /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 0000000000..1e13acf68f --- /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 0000000000..ace749f667 --- /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 0000000000..23ba2e90d1 --- /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 0000000000..fe7fd3e6aa --- /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 0000000000..8a8d81fab4 --- /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 0000000000..04d8a3844e --- /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 0000000000..d25417ea77 --- /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 0000000000..957bd88ce0 --- /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 0000000000..356f156c5d --- /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 0000000000..3fb4827ad7 --- /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 0000000000..2615c84c75 --- /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 0000000000..65d0813c3b --- /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 0000000000..7dddad9853 --- /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 0000000000..680f2a1999 --- /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 0000000000..43cfa509ca --- /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 0000000000..074ca5b402 --- /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 0000000000..a6425b6edc --- /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 0000000000..ce864844d9 --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c @@ -0,0 +1,77 @@ +#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 %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; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x12; + acl = 0x48; + rs = 0x80000000; + rt = 0x80000000; + + resulth = 0x7FFFFFFF; + resultl = 0xFFFFFFFF; + 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; + 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 %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; + 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 0000000000..6017b5e73a --- /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 0000000000..e4abb2e2af --- /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 0000000000..22ab4d57ba --- /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 = 0x04; + resultl = 0xEE9794A3; + __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 = 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) + ); + 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 0000000000..b7b73fdb66 --- /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 = 0xfdf4cbe0; + 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 0000000000..94e2bf6254 --- /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 0000000000..a1e6635631 --- /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 0000000000..21a67af216 --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/extp.c @@ -0,0 +1,44 @@ +#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); + + 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 0000000000..15ba0828fb --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/extpdp.c @@ -0,0 +1,46 @@ +#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); + + 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 0000000000..f5774eed3c --- /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 0000000000..401b94afad --- /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 0000000000..02e022427a --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/extr_r_w.c @@ -0,0 +1,71 @@ +#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); + + 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 0000000000..c3a22ee704 --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/extr_rs_w.c @@ -0,0 +1,71 @@ +#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); + + 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 0000000000..9bc2a63cc2 --- /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 0000000000..bd6b0b95c2 --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/extr_w.c @@ -0,0 +1,71 @@ +#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); + + 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 0000000000..2403b3afe4 --- /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 0000000000..ccceeb9f4c --- /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 0000000000..feac3e2e33 --- /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 0000000000..9e8b238a04 --- /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 0000000000..243b00733d --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/insv.c @@ -0,0 +1,23 @@ +#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); + + 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 0000000000..2337abea2a --- /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 0000000000..10be3b385f --- /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 0000000000..e6543c9e7e --- /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 0000000000..af4bfcfe9d --- /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 0000000000..af4bfcfe9d --- /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 0000000000..b296b20c92 --- /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 0000000000..292d68566d --- /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 = 0x05; + acli = 0xB4CB; + rs = 0xFF060000; + rt = 0xCB000000; + resulth = 0x04; + resultl = 0x947438CB; + + __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 = 0x06; + acli = 0xB4CB; + rs = 0x80000000; + rt = 0x80000000; + resulth = 0x6; + 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 0000000000..7b2ef2ab71 --- /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 = 0x05; + acli = 0xB4CB; + rs = 0xFF06; + rt = 0xCB00; + resulth = 0x04; + resultl = 0x947438CB; + + __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 = 0x06; + acli = 0xB4CB; + rs = 0x8000; + rt = 0x8000; + resulth = 0x6; + 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 0000000000..a756991723 --- /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 = 0x05; + acli = 0xB4CB; + rs = 0xFF060000; + rt = 0xCB000000; + resulth = 0x00; + resultl = 0x7FFFFFFF; + + __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 = 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) + ); + 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 0000000000..d6498f8dfd --- /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 = 0x05; + acli = 0xB4CB; + rs = 0xFF06; + rt = 0xCB00; + resulth = 0x00; + resultl = 0x7FFFFFFF; + + __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 = 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) + ); + 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 0000000000..43a80669d1 --- /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 0000000000..caeafdb05c --- /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 0000000000..c294eebb51 --- /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 0000000000..5779e6f47a --- /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 0000000000..e0f9b5a77a --- /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 0000000000..43a80669d1 --- /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 0000000000..9549aae36a --- /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 = 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; + 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 0000000000..caeafdb05c --- /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 0000000000..b3a5370fe5 --- /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 0000000000..8066d7d02a --- /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 0000000000..66a382806a --- /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 0000000000..4cc6c8f7cf --- /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 0000000000..c7206039ea --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/mulq_rs_ph.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 = 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; + 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 0000000000..15e6fde92c --- /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 0000000000..85d36c1b62 --- /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 0000000000..1f8e699925 --- /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 0000000000..929a002e75 --- /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 0000000000..a790475246 --- /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 0000000000..bf70bf7d3a --- /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 0000000000..3f885ef584 --- /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 0000000000..63b7a95683 --- /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 0000000000..31627f0bd6 --- /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 0000000000..b6f72d3cbf --- /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 0000000000..4764fd031d --- /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 0000000000..fa95c26cc4 --- /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 0000000000..021f21a744 --- /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 0000000000..03df18c72c --- /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 0000000000..634327618c --- /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 0000000000..25d45f1a9a --- /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 0000000000..fe23acce8c --- /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 0000000000..3535b37a58 --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c @@ -0,0 +1,35 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rs, rt; + int dsp; + int result; + + rs = 0x12345678; + rt = 0x87654321; + result = 0x12348765; + + __asm + ("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 + ("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 0000000000..7481d5af3a --- /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 0000000000..77a983c0d2 --- /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 0000000000..2f30285033 --- /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 0000000000..21074953bd --- /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 0000000000..6631393ea1 --- /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 0000000000..07fb15f1f7 --- /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 0000000000..dd1271fedf --- /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 0000000000..ce8ebc69c2 --- /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 0000000000..e1d6cea4b6 --- /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 0000000000..b8f1ff5285 --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/shll_ph.c @@ -0,0 +1,24 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt, dsp; + int result, resultdsp; + + rt = 0x12345678; + result = 0xA000C000; + resultdsp = 1; + + __asm + ("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); + + 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 0000000000..8c1b91c635 --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/shll_qb.c @@ -0,0 +1,36 @@ +#include<stdio.h> +#include<assert.h> + +int main() +{ + int rd, rt, dsp; + int result, resultdsp; + + rt = 0x87654321; + result = 0x87654321; + resultdsp = 0x00; + + __asm + ("shll.qb %0, %2, 0x00\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rt) + ); + dsp = (dsp >> 22) & 0x01; + assert(rd == result); + + 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; + 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 0000000000..910fea3b31 --- /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 0000000000..628c752102 --- /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 0000000000..f98a6322dc --- /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 0000000000..6d8ff4a259 --- /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 0000000000..fc9bd32765 --- /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 0000000000..350c25617a --- /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 0000000000..5b2d840a6b --- /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 0000000000..adc4ae68bd --- /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 0000000000..ec0cf2c72c --- /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 0000000000..6e42aaf8e1 --- /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 0000000000..f03b978d05 --- /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 0000000000..2ab03bb5da --- /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 0000000000..a7e4e6a5e4 --- /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 0000000000..db77f6d0e1 --- /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 0000000000..fdd7b38b64 --- /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 0000000000..8e36dadef9 --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/subq_s_ph.c @@ -0,0 +1,40 @@ +#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 + ("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 + ("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 0000000000..09022e9c85 --- /dev/null +++ b/tests/tcg/mips/mips32-dsp/subq_s_w.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 = 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; + assert(dsp == resultdsp); + assert(rd == result); + + rs = 0x66666; + rt = 0x55555; + result = 0x11111; + 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; + assert(dsp == resultdsp); + assert(rd == result); + + +#if 0 + rs = 0x35555555; + rt = 0xf5555555; + result = 0x80000000; + 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; + assert(dsp == resultdsp); + assert(rd == result); +#endif + 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 0000000000..4209096155 --- /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 0000000000..3d650533d1 --- /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 0000000000..dc54943a99 --- /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 0000000000..ed19581c7e --- /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 0000000000..af4683f304 --- /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 0000000000..921f0eaf33 --- /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 0000000000..213ba37250 --- /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 0000000000..75a75c50f3 --- /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 0000000000..de6926ebbb --- /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 0000000000..1d7a25a2a7 --- /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 0000000000..979651bfc9 --- /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 0000000000..a1f5d631b5 --- /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 0000000000..81e98c190d --- /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 0000000000..9a91e1650d --- /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 0000000000..537cf0451c --- /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 0000000000..2d6340d6fb --- /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 0000000000..a0ecdca2ac --- /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 0000000000..dba99e392c --- /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 0000000000..fae49f10eb --- /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 0000000000..ce87830246 --- /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 0000000000..798c4da5ca --- /dev/null +++ b/tests/tcg/mips/mips32-dspr2/dpaqx_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 = 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) + ); + assert(dsp >> (16 + 1) == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + 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) + ); + 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 0000000000..514797cfd1 --- /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 0000000000..f51f9b9d13 --- /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 0000000000..14cdd7c0f5 --- /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 = 0x04; + resultl = 0xAEA3E09B; + 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 0000000000..7da278eacc --- /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 0000000000..bb49a4031d --- /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 0000000000..c7e9d60d12 --- /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 0000000000..33da110de8 --- /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 0000000000..669405faf1 --- /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 = 0x80005555; + + __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 0000000000..d0f7674a38 --- /dev/null +++ b/tests/tcg/mips/mips32-dspr2/mulq_s_ph.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 = 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 0000000000..df148b7ffb --- /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 = 0x80005555; + + __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 0000000000..a6940939ca --- /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 0000000000..06c91a43e7 --- /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 0000000000..3a2b3fde05 --- /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 0000000000..5c9baab03d --- /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 0000000000..6474a108c0 --- /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 0000000000..f6bcd47b2d --- /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 0000000000..48193de87a --- /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 0000000000..29afa0e4b0 --- /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 0000000000..b21e1b7ca6 --- /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 0000000000..9ea8aa0cbb --- /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 0000000000..724b9a7a46 --- /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 0000000000..ac79aa69ac --- /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 0000000000..dbc096734c --- /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 0000000000..24ef0f1aeb --- /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 0000000000..d460f8630f --- /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 0000000000..42be3deb80 --- /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 0000000000..0d39a017c7 --- /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 0000000000..8e4da4f3e5 --- /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 0000000000..92cfc764b8 --- /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 0000000000..dac81d47db --- /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 0000000000..b2ac6b3ffd --- /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 0000000000..6214031578 --- /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 0000000000..238416d438 --- /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 0000000000..48fc763b4f --- /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 0000000000..9001a9e164 --- /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 0000000000..414c8bd3f6 --- /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 0000000000..22a36d9805 --- /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 0000000000..99a7668c0c --- /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 0000000000..4b874afb8a --- /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 0000000000..ad84cdcfe0 --- /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 0000000000..2e380bbfc5 --- /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 0000000000..b638a2b93a --- /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 0000000000..3e08f5d482 --- /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 0000000000..4b684b9b99 --- /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 0000000000..17f9c668c0 --- /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 0000000000..3b9b5fc5bb --- /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 0000000000..e89a4638b7 --- /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 0000000000..cb84293ade --- /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 0000000000..5929cd2f5c --- /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 0000000000..ac24ef3f5c --- /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 0000000000..97bce44602 --- /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 0000000000..36161ad852 --- /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 0000000000..63069d0dab --- /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 0000000000..bae4c06ccb --- /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 0000000000..49ea271003 --- /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 0000000000..12d24f1783 --- /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 0000000000..6acc43cd5b --- /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 0000000000..c9ce21667f --- /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 0000000000..1d91228c3a --- /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 0000000000..87e74caf38 --- /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 0000000000..0a13a5eaae --- /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 0000000000..697d73dd1a --- /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 0000000000..b41c4430fd --- /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 0000000000..8b65f18c00 --- /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 0000000000..dd2b091f61 --- /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 0000000000..3e5c9dd6da --- /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 0000000000..a467cb78db --- /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 0000000000..4d1983e5ea --- /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 0000000000..28f3bec252 --- /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 0000000000..8acbd1c4ba --- /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 0000000000..8a17a08513 --- /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 0000000000..34e312d818 --- /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 0000000000..adb75eed52 --- /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 0000000000..ba8e12182e --- /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 0000000000..a469cc0366 --- /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 0000000000..a2361e2d42 --- /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 0000000000..09c0b5b412 --- /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 0000000000..2626f3d98c --- /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 0000000000..538846df18 --- /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 0000000000..a10a9ab40e --- /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 0000000000..2774e9bfcc --- /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 0000000000..1a202fefa2 --- /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 0000000000..ebe5f99db0 --- /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 0000000000..1adb5549a9 --- /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 0000000000..79bed5da35 --- /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 0000000000..2e6187f729 --- /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 0000000000..b47a0177d4 --- /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 0000000000..cd201deb21 --- /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 0000000000..6ce4185462 --- /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 0000000000..a65183c030 --- /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 0000000000..87d3aeedce --- /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 0000000000..973765c1c0 --- /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 0000000000..f6192188c0 --- /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 0000000000..fb22614725 --- /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 0000000000..39ab0c10db --- /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 0000000000..16be6170e4 --- /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 0000000000..cc4838ad5f --- /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 0000000000..027555fb53 --- /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 0000000000..1bca935008 --- /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 0000000000..844a347429 --- /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 0000000000..1bb2ec2f26 --- /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 0000000000..f840cdd761 --- /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 0000000000..54905e8f93 --- /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 0000000000..d7aa60b4b1 --- /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 0000000000..fcfd764310 --- /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 0000000000..3282461a7d --- /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 0000000000..7660f037da --- /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 0000000000..2cc50c577e --- /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 0000000000..7fc2503fc5 --- /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 0000000000..f55afc9095 --- /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 0000000000..c0a8f4d7aa --- /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 0000000000..aa0d47a065 --- /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 0000000000..da6dbb6154 --- /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 0000000000..bf00b70aa7 --- /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 0000000000..f50584b9c4 --- /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 0000000000..792bd23730 --- /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 0000000000..c72f54bace --- /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 0000000000..f430193841 --- /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 0000000000..ba57426d22 --- /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 0000000000..158472bf93 --- /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 0000000000..94572ad154 --- /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 0000000000..73551f96b3 --- /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 0000000000..de10cb57a5 --- /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 0000000000..bd69576687 --- /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 0000000000..8379729787 --- /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 0000000000..8707cd1174 --- /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 0000000000..b6dcaebcbc --- /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 0000000000..8adffb3954 --- /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 0000000000..9a099ae42f --- /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 0000000000..fc5696f4c4 --- /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 0000000000..b7db61d7c1 --- /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 0000000000..dbdc87bffe --- /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 0000000000..787d9f00b4 --- /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 0000000000..2020e56866 --- /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 0000000000..6a81414d65 --- /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 0000000000..de6e44fbc5 --- /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 0000000000..e9f426a374 --- /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 0000000000..c196b43537 --- /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 0000000000..e2af69fe2c --- /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 0000000000..7dba8746e5 --- /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 0000000000..138ee2a691 --- /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 0000000000..234a0af293 --- /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 0000000000..8768cbaa3d --- /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 0000000000..5006e2be34 --- /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 0000000000..1d213a51b5 --- /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 0000000000..5530ffbe69 --- /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 0000000000..b611cfa91a --- /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 0000000000..136ff2d77b --- /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 0000000000..dd0ae1cca2 --- /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 0000000000..a3de6f8e2e --- /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 0000000000..f02173736a --- /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 0000000000..ee915f796e --- /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 0000000000..cdc646b5fc --- /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 0000000000..bd7c0c0f3f --- /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 0000000000..2c91cb4c59 --- /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 0000000000..75066b5916 --- /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 0000000000..55f8ae046f --- /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 0000000000..857005139b --- /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 0000000000..957cd426f0 --- /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 0000000000..304fffbe7c --- /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 0000000000..6c68d45afe --- /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 0000000000..fa8b41fd39 --- /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 0000000000..997a9f64d9 --- /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 0000000000..0e594794dd --- /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 0000000000..2f444c9f85 --- /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 0000000000..8bd0e9942c --- /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 0000000000..db0d386e88 --- /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 0000000000..52ed9c095a --- /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 0000000000..fd6233d4df --- /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 0000000000..7863c05912 --- /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 0000000000..02548f85cf --- /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 0000000000..92d7a0b4f2 --- /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 0000000000..4a294d1a0c --- /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 0000000000..21a8a7c77d --- /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 0000000000..3722b0ae6c --- /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 0000000000..7807418834 --- /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 0000000000..160049ffd4 --- /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 0000000000..8800c14d1e --- /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 0000000000..24d80f551a --- /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 0000000000..0d5de9db9e --- /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 0000000000..aa2e2938af --- /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 0000000000..64551007cf --- /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 0000000000..1e05339d23 --- /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 0000000000..f44b940492 --- /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 0000000000..f0f78f43c5 --- /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 0000000000..709d4f9004 --- /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 0000000000..4d071ec863 --- /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 0000000000..4ed3fc030c --- /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 0000000000..e2ea0933b2 --- /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 0000000000..17b73311dc --- /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 0000000000..15e94946b1 --- /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 0000000000..495368ce0b --- /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 0000000000..7c6636975c --- /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 0000000000..176d2365a8 --- /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 0000000000..93a36a4855 --- /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 0000000000..121473083b --- /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 0000000000..3aa0e096ca --- /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 0000000000..81f7917c19 --- /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 0000000000..38cf6a62b9 --- /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 0000000000..70c32b6716 --- /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 0000000000..c6638aaafd --- /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 0000000000..63f9373b08 --- /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 0000000000..5fb65e4049 --- /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 0000000000..9af3b6372e --- /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 0000000000..fd04083371 --- /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 0000000000..ce2da79af8 --- /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 0000000000..8bb16de9af --- /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 0000000000..734ac322e7 --- /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 0000000000..4f61b1709e --- /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 0000000000..f0946abdcb --- /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 0000000000..da957c0743 --- /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 0000000000..f417c9f342 --- /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 0000000000..4a4ffef8ea --- /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 0000000000..61da3331fb --- /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 0000000000..ac78728abf --- /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 0000000000..e27c36b7fd --- /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 0000000000..cb1fee4508 --- /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 0000000000..b4208c2dab --- /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 0000000000..d91bd2023c --- /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 0000000000..cf8676d390 --- /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 0000000000..76ddf25fb9 --- /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 0000000000..c9d6535bba --- /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 0000000000..7165572435 --- /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 0000000000..20cb780136 --- /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 0000000000..11d29bdbc2 --- /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 0000000000..d35376a2a3 --- /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 0000000000..592feaecb0 --- /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 0000000000..82afc37167 --- /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 0000000000..31ff3186d3 --- /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 0000000000..0af7a36b40 --- /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 0000000000..e1789af4c8 --- /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 0000000000..d99298c31e --- /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 0000000000..5f454f69e0 --- /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 0000000000..e82615a8c9 --- /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 0000000000..7dcb58ff46 --- /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 0000000000..42b462d20d --- /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 0000000000..d7878b2792 --- /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 0000000000..c21ab6698a --- /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 0000000000..1380825a32 --- /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 0000000000..1cf5d6da6e --- /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 0000000000..e38f6860c7 --- /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 0000000000..f2f57fa27a --- /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 0000000000..57800615d2 --- /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 0000000000..96a2e6f55f --- /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 0000000000..532291f3fb --- /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 0000000000..8d4ec295bd --- /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 0000000000..e49356b8ec --- /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 0000000000..0de4077e7d --- /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 0000000000..7e69f941f4 --- /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 0000000000..f8dc8d2964 --- /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 0000000000..db3832d091 --- /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 0000000000..5f6af8b8c0 --- /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 0000000000..d7fcfa816b --- /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 0000000000..a2dc014742 --- /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 0000000000..33b1b8fe72 --- /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 0000000000..85dbfef3ea --- /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 0000000000..184709443e --- /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 0000000000..e0943ad474 --- /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 0000000000..6a86e684b8 --- /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 0000000000..d5c2110efe --- /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 0000000000..36d2c9c887 --- /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 0000000000..1b4e983746 --- /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 0000000000..e19d515797 --- /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 0000000000..dc92e09d44 --- /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 0000000000..350d5294fc --- /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 0000000000..25b0545931 --- /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 0000000000..fd187a1e0b --- /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 0000000000..3766c7255c --- /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 0000000000..a1145713a0 --- /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 0000000000..c0e36dba10 --- /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 0000000000..c1562463e0 --- /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 0000000000..cb39c46716 --- /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 0000000000..5616aa9c5b --- /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 0000000000..05de2fd6c8 --- /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 0000000000..6a1b18610c --- /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 0000000000..32f96ba4bd --- /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 0000000000..76d5f0a10a --- /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 0000000000..0b162f07ea --- /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 0000000000..e8e0b0567e --- /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 0000000000..4053b6b884 --- /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 0000000000..91d32da172 --- /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 0000000000..f670967113 --- /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 0000000000..9eb80df379 --- /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 0000000000..5df64e5ff0 --- /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 0000000000..9de76f4a1f --- /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 0000000000..3033fd88d1 --- /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 0000000000..c75a91451c --- /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 0000000000..ba44bb9c0e --- /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 0000000000..f7aec3e568 --- /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 0000000000..6b43cb8d06 --- /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 0000000000..890ec98d9b --- /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 0000000000..d324decbd3 --- /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 0000000000..78559e6784 --- /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 0000000000..d64c8cde8a --- /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 0000000000..edcbf342ce --- /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 0000000000..9250edb45c --- /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 0000000000..b0c1626251 --- /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 0000000000..9b309f6f16 --- /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 0000000000..796b409a86 --- /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 0000000000..832de833ef --- /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 0000000000..ae65fa5e18 --- /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 0000000000..68a7cecc4b --- /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 0000000000..7fbe815782 --- /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 0000000000..61217f38cf --- /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 0000000000..c63f6480eb --- /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 0000000000..b3da098189 --- /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 0000000000..f0a60ea4e0 --- /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 0000000000..d80b4e6ab9 --- /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 0000000000..a71e4e307f --- /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 0000000000..c7431b1857 --- /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 0000000000..39dc99aa55 --- /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 0000000000..1411e44be3 --- /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 0000000000..51252fb980 --- /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 0000000000..18d6b3a98e --- /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 0000000000..9d595fc14a --- /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 0000000000..99f292ecb2 --- /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 0000000000..61277eb30c --- /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 0000000000..ba46a92698 --- /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 0000000000..24c888134d --- /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 0000000000..b6291b5eb6 --- /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 0000000000..9a099ae42f --- /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 0000000000..b7db61d7c1 --- /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 0000000000..bd7c0c0f3f --- /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 0000000000..5a3d05cb29 --- /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 0000000000..7c8b2c718f --- /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 0000000000..ffdc66d54a --- /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 0000000000..b8c20c68cc --- /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 0000000000..db74b713f2 --- /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 0000000000..5b22a60a8d --- /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 0000000000..835a73d479 --- /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 0000000000..80d5e8dce9 --- /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 0000000000..b1d7bcdf8e --- /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 0000000000..62d220dcae --- /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 0000000000..4ab083e969 --- /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 0000000000..cf8676d390 --- /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 0000000000..cac3102355 --- /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 0000000000..9c64f75bd4 --- /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 0000000000..fbdfbab35a --- /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 0000000000..a716203d80 --- /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 0000000000..b80100a7c2 --- /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 0000000000..009080b2a7 --- /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 0000000000..e32d976625 --- /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 0000000000..58c5488b58 --- /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 0000000000..90374019ae --- /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 0000000000..b8f9d2fee6 --- /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 0000000000..b025e40a35 --- /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 0000000000..65f17603d8 --- /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 0000000000..60a6b1b7da --- /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 0000000000..911cb349d4 --- /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 0000000000..ae32cc06f5 --- /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 0000000000..de7a29e775 --- /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 0000000000..3fc452bf8e --- /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 0000000000..aac7a834ee --- /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 0000000000..fc20ffd09e --- /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 0000000000..66d4680440 --- /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/test-i386-fprem.c b/tests/tcg/test-i386-fprem.c new file mode 100644 index 0000000000..e91fb1ae93 --- /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.c b/tests/tcg/test-i386.c index 8e64bbaf38..6dc730d882 100644 --- a/tests/tcg/test-i386.c +++ b/tests/tcg/test-i386.c @@ -17,6 +17,7 @@ * 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> @@ -784,7 +785,7 @@ void fpu_clear_exceptions(void) long double fpregs[8]; } float_env32; - asm volatile ("fnstenv %0\n" : : "m" (float_env32)); + asm volatile ("fnstenv %0\n" : "=m" (float_env32)); float_env32.fpus &= ~0x7f; asm volatile ("fldenv %0\n" : : "m" (float_env32)); } @@ -1827,7 +1828,7 @@ void test_exceptions(void) printf("lock nop exception:\n"); if (setjmp(jmp_env) == 0) { /* now execute an invalid instruction */ - asm volatile("lock nop"); + asm volatile(".byte 0xf0, 0x90"); /* lock nop */ } printf("INT exception:\n"); diff --git a/tests/tcg/test-mmap.c b/tests/tcg/test-mmap.c index c418b67660..3982fa2c72 100644 --- a/tests/tcg/test-mmap.c +++ b/tests/tcg/test-mmap.c @@ -429,6 +429,12 @@ void check_file_fixed_mmaps(void) 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"; @@ -450,13 +456,15 @@ int main(int argc, char **argv) unlink(tempname); /* Fill the file with int's counting from zero and up. */ - for (i = 0; i < (pagesize * 4) / sizeof i; i++) - write (test_fd, &i, sizeof i); + 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. */ - write (test_fd, &i, sizeof i); i++; - write (test_fd, &i, sizeof i); i++; - write (test_fd, &i, sizeof i); i++; + 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); diff --git a/tests/tcg/test_path.c b/tests/tcg/test_path.c index 7265a9445d..a064eea8fb 100644 --- a/tests/tcg/test_path.c +++ b/tests/tcg/test_path.c @@ -1,11 +1,12 @@ /* Test path override code */ -#include "../config-host.h" -#include "../qemu-malloc.c" -#include "../cutils.c" -#include "../path.c" -#include "../trace.c" +#define _GNU_SOURCE +#include "config-host.h" +#include "iov.c" +#include "cutils.c" +#include "path.c" +#include "trace.c" #ifdef CONFIG_TRACE_SIMPLE -#include "../simpletrace.c" +#include "../trace/simple.c" #endif #include <stdarg.h> diff --git a/tests/tcg/testthread.c b/tests/tcg/testthread.c index 27e4825bc6..2679af119a 100644 --- a/tests/tcg/testthread.c +++ b/tests/tcg/testthread.c @@ -1,3 +1,4 @@ +#include <assert.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -8,6 +9,12 @@ #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; @@ -15,7 +22,7 @@ void *thread1_func(void *arg) for(i=0;i<10;i++) { snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg); - write(1, buf, strlen(buf)); + checked_write(1, buf, strlen(buf)); usleep(100 * 1000); } return NULL; @@ -27,7 +34,7 @@ void *thread2_func(void *arg) char buf[512]; for(i=0;i<20;i++) { snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg); - write(1, buf, strlen(buf)); + checked_write(1, buf, strlen(buf)); usleep(150 * 1000); } return NULL; diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile index 0ff0ccfb8c..002fd871d9 100644 --- a/tests/tcg/xtensa/Makefile +++ b/tests/tcg/xtensa/Makefile @@ -42,9 +42,11 @@ 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 diff --git a/tests/tcg/xtensa/macros.inc b/tests/tcg/xtensa/macros.inc index 23bf3e96c8..c9be1ce516 100644 --- a/tests/tcg/xtensa/macros.inc +++ b/tests/tcg/xtensa/macros.inc @@ -1,7 +1,7 @@ .macro test_suite name .data status: .word result -result: .space 20 +result: .space 256 .text .global main .align 4 diff --git a/tests/tcg/xtensa/test_s32c1i.S b/tests/tcg/xtensa/test_s32c1i.S new file mode 100644 index 0000000000..4536015a84 --- /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_sr.S b/tests/tcg/xtensa/test_sr.S new file mode 100644 index 0000000000..470c03dae2 --- /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/test-aio.c b/tests/test-aio.c new file mode 100644 index 0000000000..e4ebef76b9 --- /dev/null +++ b/tests/test-aio.c @@ -0,0 +1,666 @@ +/* + * AioContext tests + * + * Copyright Red Hat, Inc. 2012 + * + * Authors: + * Paolo Bonzini <pbonzini@redhat.com> + * + * This work is licensed under the terms of the GNU LGPL, version 2 or later. + * See the COPYING.LIB file in the top-level directory. + */ + +#include <glib.h> +#include "block/aio.h" + +AioContext *ctx; + +/* Wait until there are no more BHs or AIO requests */ +static void wait_for_aio(void) +{ + while (aio_poll(ctx, true)) { + /* Do nothing */ + } +} + +/* Simple callbacks for testing. */ + +typedef struct { + QEMUBH *bh; + int n; + int max; +} BHTestData; + +static void bh_test_cb(void *opaque) +{ + BHTestData *data = opaque; + if (++data->n < data->max) { + qemu_bh_schedule(data->bh); + } +} + +static void bh_delete_cb(void *opaque) +{ + BHTestData *data = opaque; + if (++data->n < data->max) { + qemu_bh_schedule(data->bh); + } else { + qemu_bh_delete(data->bh); + data->bh = NULL; + } +} + +typedef struct { + EventNotifier e; + int n; + int active; + bool auto_set; +} EventNotifierTestData; + +static int event_active_cb(EventNotifier *e) +{ + EventNotifierTestData *data = container_of(e, EventNotifierTestData, e); + return data->active > 0; +} + +static void event_ready_cb(EventNotifier *e) +{ + EventNotifierTestData *data = container_of(e, EventNotifierTestData, e); + g_assert(event_notifier_test_and_clear(e)); + data->n++; + if (data->active > 0) { + data->active--; + } + if (data->auto_set && data->active) { + event_notifier_set(e); + } +} + +/* Tests using aio_*. */ + +static void test_notify(void) +{ + g_assert(!aio_poll(ctx, false)); + aio_notify(ctx); + g_assert(!aio_poll(ctx, true)); + g_assert(!aio_poll(ctx, false)); +} + +static void test_bh_schedule(void) +{ + BHTestData data = { .n = 0 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + g_assert(aio_poll(ctx, true)); + g_assert_cmpint(data.n, ==, 1); + + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 1); + qemu_bh_delete(data.bh); +} + +static void test_bh_schedule10(void) +{ + BHTestData data = { .n = 0, .max = 10 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + g_assert(aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 1); + + g_assert(aio_poll(ctx, true)); + g_assert_cmpint(data.n, ==, 2); + + wait_for_aio(); + g_assert_cmpint(data.n, ==, 10); + + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 10); + qemu_bh_delete(data.bh); +} + +static void test_bh_cancel(void) +{ + BHTestData data = { .n = 0 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + qemu_bh_cancel(data.bh); + g_assert_cmpint(data.n, ==, 0); + + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 0); + qemu_bh_delete(data.bh); +} + +static void test_bh_delete(void) +{ + BHTestData data = { .n = 0 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + qemu_bh_delete(data.bh); + g_assert_cmpint(data.n, ==, 0); + + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 0); +} + +static void test_bh_delete_from_cb(void) +{ + BHTestData data1 = { .n = 0, .max = 1 }; + + data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); + + qemu_bh_schedule(data1.bh); + g_assert_cmpint(data1.n, ==, 0); + + wait_for_aio(); + g_assert_cmpint(data1.n, ==, data1.max); + g_assert(data1.bh == NULL); + + g_assert(!aio_poll(ctx, false)); + g_assert(!aio_poll(ctx, true)); +} + +static void test_bh_delete_from_cb_many(void) +{ + BHTestData data1 = { .n = 0, .max = 1 }; + BHTestData data2 = { .n = 0, .max = 3 }; + BHTestData data3 = { .n = 0, .max = 2 }; + BHTestData data4 = { .n = 0, .max = 4 }; + + data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); + data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2); + data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3); + data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4); + + qemu_bh_schedule(data1.bh); + qemu_bh_schedule(data2.bh); + qemu_bh_schedule(data3.bh); + qemu_bh_schedule(data4.bh); + g_assert_cmpint(data1.n, ==, 0); + g_assert_cmpint(data2.n, ==, 0); + g_assert_cmpint(data3.n, ==, 0); + g_assert_cmpint(data4.n, ==, 0); + + g_assert(aio_poll(ctx, false)); + g_assert_cmpint(data1.n, ==, 1); + g_assert_cmpint(data2.n, ==, 1); + g_assert_cmpint(data3.n, ==, 1); + g_assert_cmpint(data4.n, ==, 1); + g_assert(data1.bh == NULL); + + wait_for_aio(); + g_assert_cmpint(data1.n, ==, data1.max); + g_assert_cmpint(data2.n, ==, data2.max); + g_assert_cmpint(data3.n, ==, data3.max); + g_assert_cmpint(data4.n, ==, data4.max); + g_assert(data1.bh == NULL); + g_assert(data2.bh == NULL); + g_assert(data3.bh == NULL); + g_assert(data4.bh == NULL); +} + +static void test_bh_flush(void) +{ + BHTestData data = { .n = 0 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + wait_for_aio(); + g_assert_cmpint(data.n, ==, 1); + + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 1); + qemu_bh_delete(data.bh); +} + +static void test_set_event_notifier(void) +{ + EventNotifierTestData data = { .n = 0, .active = 0 }; + event_notifier_init(&data.e, false); + aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb); + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 0); + + aio_set_event_notifier(ctx, &data.e, NULL, NULL); + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 0); + event_notifier_cleanup(&data.e); +} + +static void test_wait_event_notifier(void) +{ + EventNotifierTestData data = { .n = 0, .active = 1 }; + event_notifier_init(&data.e, false); + aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb); + g_assert(aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 0); + g_assert_cmpint(data.active, ==, 1); + + event_notifier_set(&data.e); + g_assert(aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 1); + g_assert_cmpint(data.active, ==, 0); + + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 1); + g_assert_cmpint(data.active, ==, 0); + + aio_set_event_notifier(ctx, &data.e, NULL, NULL); + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 1); + + event_notifier_cleanup(&data.e); +} + +static void test_flush_event_notifier(void) +{ + EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true }; + event_notifier_init(&data.e, false); + aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb); + g_assert(aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 0); + g_assert_cmpint(data.active, ==, 10); + + event_notifier_set(&data.e); + g_assert(aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 1); + g_assert_cmpint(data.active, ==, 9); + g_assert(aio_poll(ctx, false)); + + wait_for_aio(); + g_assert_cmpint(data.n, ==, 10); + g_assert_cmpint(data.active, ==, 0); + g_assert(!aio_poll(ctx, false)); + + aio_set_event_notifier(ctx, &data.e, NULL, NULL); + g_assert(!aio_poll(ctx, false)); + event_notifier_cleanup(&data.e); +} + +static void test_wait_event_notifier_noflush(void) +{ + EventNotifierTestData data = { .n = 0 }; + EventNotifierTestData dummy = { .n = 0, .active = 1 }; + + event_notifier_init(&data.e, false); + aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL); + + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 0); + + /* Until there is an active descriptor, aio_poll may or may not call + * event_ready_cb. Still, it must not block. */ + event_notifier_set(&data.e); + g_assert(!aio_poll(ctx, true)); + data.n = 0; + + /* An active event notifier forces aio_poll to look at EventNotifiers. */ + event_notifier_init(&dummy.e, false); + aio_set_event_notifier(ctx, &dummy.e, event_ready_cb, event_active_cb); + + event_notifier_set(&data.e); + g_assert(aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 1); + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 1); + + event_notifier_set(&data.e); + g_assert(aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 2); + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 2); + + event_notifier_set(&dummy.e); + wait_for_aio(); + g_assert_cmpint(data.n, ==, 2); + g_assert_cmpint(dummy.n, ==, 1); + g_assert_cmpint(dummy.active, ==, 0); + + aio_set_event_notifier(ctx, &dummy.e, NULL, NULL); + event_notifier_cleanup(&dummy.e); + + aio_set_event_notifier(ctx, &data.e, NULL, NULL); + g_assert(!aio_poll(ctx, false)); + g_assert_cmpint(data.n, ==, 2); + + event_notifier_cleanup(&data.e); +} + +/* Now the same tests, using the context as a GSource. They are + * very similar to the ones above, with g_main_context_iteration + * replacing aio_poll. However: + * - sometimes both the AioContext and the glib main loop wake + * themselves up. Hence, some "g_assert(!aio_poll(ctx, false));" + * are replaced by "while (g_main_context_iteration(NULL, false));". + * - there is no exact replacement for a blocking wait. + * "while (g_main_context_iteration(NULL, true)" seems to work, + * but it is not documented _why_ it works. For these tests a + * non-blocking loop like "while (g_main_context_iteration(NULL, false)" + * works well, and that's what I am using. + */ + +static void test_source_notify(void) +{ + while (g_main_context_iteration(NULL, false)); + aio_notify(ctx); + g_assert(g_main_context_iteration(NULL, true)); + g_assert(!g_main_context_iteration(NULL, false)); +} + +static void test_source_flush(void) +{ + g_assert(!g_main_context_iteration(NULL, false)); + aio_notify(ctx); + while (g_main_context_iteration(NULL, false)); + g_assert(!g_main_context_iteration(NULL, false)); +} + +static void test_source_bh_schedule(void) +{ + BHTestData data = { .n = 0 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + g_assert(g_main_context_iteration(NULL, true)); + g_assert_cmpint(data.n, ==, 1); + + g_assert(!g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 1); + qemu_bh_delete(data.bh); +} + +static void test_source_bh_schedule10(void) +{ + BHTestData data = { .n = 0, .max = 10 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + g_assert(g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 1); + + g_assert(g_main_context_iteration(NULL, true)); + g_assert_cmpint(data.n, ==, 2); + + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 10); + + g_assert(!g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 10); + qemu_bh_delete(data.bh); +} + +static void test_source_bh_cancel(void) +{ + BHTestData data = { .n = 0 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + qemu_bh_cancel(data.bh); + g_assert_cmpint(data.n, ==, 0); + + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 0); + qemu_bh_delete(data.bh); +} + +static void test_source_bh_delete(void) +{ + BHTestData data = { .n = 0 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + qemu_bh_delete(data.bh); + g_assert_cmpint(data.n, ==, 0); + + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 0); +} + +static void test_source_bh_delete_from_cb(void) +{ + BHTestData data1 = { .n = 0, .max = 1 }; + + data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); + + qemu_bh_schedule(data1.bh); + g_assert_cmpint(data1.n, ==, 0); + + g_main_context_iteration(NULL, true); + g_assert_cmpint(data1.n, ==, data1.max); + g_assert(data1.bh == NULL); + + g_assert(!g_main_context_iteration(NULL, false)); +} + +static void test_source_bh_delete_from_cb_many(void) +{ + BHTestData data1 = { .n = 0, .max = 1 }; + BHTestData data2 = { .n = 0, .max = 3 }; + BHTestData data3 = { .n = 0, .max = 2 }; + BHTestData data4 = { .n = 0, .max = 4 }; + + data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); + data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2); + data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3); + data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4); + + qemu_bh_schedule(data1.bh); + qemu_bh_schedule(data2.bh); + qemu_bh_schedule(data3.bh); + qemu_bh_schedule(data4.bh); + g_assert_cmpint(data1.n, ==, 0); + g_assert_cmpint(data2.n, ==, 0); + g_assert_cmpint(data3.n, ==, 0); + g_assert_cmpint(data4.n, ==, 0); + + g_assert(g_main_context_iteration(NULL, false)); + g_assert_cmpint(data1.n, ==, 1); + g_assert_cmpint(data2.n, ==, 1); + g_assert_cmpint(data3.n, ==, 1); + g_assert_cmpint(data4.n, ==, 1); + g_assert(data1.bh == NULL); + + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data1.n, ==, data1.max); + g_assert_cmpint(data2.n, ==, data2.max); + g_assert_cmpint(data3.n, ==, data3.max); + g_assert_cmpint(data4.n, ==, data4.max); + g_assert(data1.bh == NULL); + g_assert(data2.bh == NULL); + g_assert(data3.bh == NULL); + g_assert(data4.bh == NULL); +} + +static void test_source_bh_flush(void) +{ + BHTestData data = { .n = 0 }; + data.bh = aio_bh_new(ctx, bh_test_cb, &data); + + qemu_bh_schedule(data.bh); + g_assert_cmpint(data.n, ==, 0); + + g_assert(g_main_context_iteration(NULL, true)); + g_assert_cmpint(data.n, ==, 1); + + g_assert(!g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 1); + qemu_bh_delete(data.bh); +} + +static void test_source_set_event_notifier(void) +{ + EventNotifierTestData data = { .n = 0, .active = 0 }; + event_notifier_init(&data.e, false); + aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb); + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 0); + + aio_set_event_notifier(ctx, &data.e, NULL, NULL); + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 0); + event_notifier_cleanup(&data.e); +} + +static void test_source_wait_event_notifier(void) +{ + EventNotifierTestData data = { .n = 0, .active = 1 }; + event_notifier_init(&data.e, false); + aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb); + g_assert(g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 0); + g_assert_cmpint(data.active, ==, 1); + + event_notifier_set(&data.e); + g_assert(g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 1); + g_assert_cmpint(data.active, ==, 0); + + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 1); + g_assert_cmpint(data.active, ==, 0); + + aio_set_event_notifier(ctx, &data.e, NULL, NULL); + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 1); + + event_notifier_cleanup(&data.e); +} + +static void test_source_flush_event_notifier(void) +{ + EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true }; + event_notifier_init(&data.e, false); + aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb); + g_assert(g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 0); + g_assert_cmpint(data.active, ==, 10); + + event_notifier_set(&data.e); + g_assert(g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 1); + g_assert_cmpint(data.active, ==, 9); + g_assert(g_main_context_iteration(NULL, false)); + + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 10); + g_assert_cmpint(data.active, ==, 0); + g_assert(!g_main_context_iteration(NULL, false)); + + aio_set_event_notifier(ctx, &data.e, NULL, NULL); + while (g_main_context_iteration(NULL, false)); + event_notifier_cleanup(&data.e); +} + +static void test_source_wait_event_notifier_noflush(void) +{ + EventNotifierTestData data = { .n = 0 }; + EventNotifierTestData dummy = { .n = 0, .active = 1 }; + + event_notifier_init(&data.e, false); + aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL); + + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 0); + + /* Until there is an active descriptor, glib may or may not call + * event_ready_cb. Still, it must not block. */ + event_notifier_set(&data.e); + g_main_context_iteration(NULL, true); + data.n = 0; + + /* An active event notifier forces aio_poll to look at EventNotifiers. */ + event_notifier_init(&dummy.e, false); + aio_set_event_notifier(ctx, &dummy.e, event_ready_cb, event_active_cb); + + event_notifier_set(&data.e); + g_assert(g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 1); + g_assert(!g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 1); + + event_notifier_set(&data.e); + g_assert(g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 2); + g_assert(!g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 2); + + event_notifier_set(&dummy.e); + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 2); + g_assert_cmpint(dummy.n, ==, 1); + g_assert_cmpint(dummy.active, ==, 0); + + aio_set_event_notifier(ctx, &dummy.e, NULL, NULL); + event_notifier_cleanup(&dummy.e); + + aio_set_event_notifier(ctx, &data.e, NULL, NULL); + while (g_main_context_iteration(NULL, false)); + g_assert_cmpint(data.n, ==, 2); + + event_notifier_cleanup(&data.e); +} + +/* End of tests. */ + +int main(int argc, char **argv) +{ + GSource *src; + + ctx = aio_context_new(); + src = aio_get_g_source(ctx); + g_source_attach(src, NULL); + g_source_unref(src); + + while (g_main_context_iteration(NULL, false)); + + g_test_init(&argc, &argv, NULL); + g_test_add_func("/aio/notify", test_notify); + g_test_add_func("/aio/bh/schedule", test_bh_schedule); + g_test_add_func("/aio/bh/schedule10", test_bh_schedule10); + g_test_add_func("/aio/bh/cancel", test_bh_cancel); + g_test_add_func("/aio/bh/delete", test_bh_delete); + g_test_add_func("/aio/bh/callback-delete/one", test_bh_delete_from_cb); + g_test_add_func("/aio/bh/callback-delete/many", test_bh_delete_from_cb_many); + g_test_add_func("/aio/bh/flush", test_bh_flush); + g_test_add_func("/aio/event/add-remove", test_set_event_notifier); + g_test_add_func("/aio/event/wait", test_wait_event_notifier); + g_test_add_func("/aio/event/wait/no-flush-cb", test_wait_event_notifier_noflush); + g_test_add_func("/aio/event/flush", test_flush_event_notifier); + + g_test_add_func("/aio-gsource/notify", test_source_notify); + g_test_add_func("/aio-gsource/flush", test_source_flush); + g_test_add_func("/aio-gsource/bh/schedule", test_source_bh_schedule); + g_test_add_func("/aio-gsource/bh/schedule10", test_source_bh_schedule10); + g_test_add_func("/aio-gsource/bh/cancel", test_source_bh_cancel); + g_test_add_func("/aio-gsource/bh/delete", test_source_bh_delete); + g_test_add_func("/aio-gsource/bh/callback-delete/one", test_source_bh_delete_from_cb); + g_test_add_func("/aio-gsource/bh/callback-delete/many", test_source_bh_delete_from_cb_many); + g_test_add_func("/aio-gsource/bh/flush", test_source_bh_flush); + g_test_add_func("/aio-gsource/event/add-remove", test_source_set_event_notifier); + g_test_add_func("/aio-gsource/event/wait", test_source_wait_event_notifier); + g_test_add_func("/aio-gsource/event/wait/no-flush-cb", test_source_wait_event_notifier_noflush); + g_test_add_func("/aio-gsource/event/flush", test_source_flush_event_notifier); + return g_test_run(); +} diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c index e5d14eb696..4c6cc81fb9 100644 --- a/tests/test-coroutine.c +++ b/tests/test-coroutine.c @@ -12,7 +12,7 @@ */ #include <glib.h> -#include "qemu-coroutine.h" +#include "block/coroutine.h" /* * Check that qemu_in_coroutine() works diff --git a/tests/test-iov.c b/tests/test-iov.c index cbe7a8955c..46e4dddc55 100644 --- a/tests/test-iov.c +++ b/tests/test-iov.c @@ -1,7 +1,7 @@ #include <glib.h> #include "qemu-common.h" -#include "iov.h" -#include "qemu_socket.h" +#include "qemu/iov.h" +#include "qemu/sockets.h" /* create a randomly-sized iovec with random vectors */ static void iov_random(struct iovec **iovp, unsigned *iov_cntp) @@ -250,11 +250,161 @@ static void test_io(void) #endif } +static void test_discard_front(void) +{ + struct iovec *iov; + struct iovec *iov_tmp; + unsigned int iov_cnt; + unsigned int iov_cnt_tmp; + void *old_base; + size_t size; + size_t ret; + + /* Discard zero bytes */ + iov_random(&iov, &iov_cnt); + iov_tmp = iov; + iov_cnt_tmp = iov_cnt; + ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, 0); + g_assert(ret == 0); + g_assert(iov_tmp == iov); + g_assert(iov_cnt_tmp == iov_cnt); + iov_free(iov, iov_cnt); + + /* Discard more bytes than vector size */ + iov_random(&iov, &iov_cnt); + iov_tmp = iov; + iov_cnt_tmp = iov_cnt; + size = iov_size(iov, iov_cnt); + ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size + 1); + g_assert(ret == size); + g_assert(iov_cnt_tmp == 0); + iov_free(iov, iov_cnt); + + /* Discard entire vector */ + iov_random(&iov, &iov_cnt); + iov_tmp = iov; + iov_cnt_tmp = iov_cnt; + size = iov_size(iov, iov_cnt); + ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size); + g_assert(ret == size); + g_assert(iov_cnt_tmp == 0); + iov_free(iov, iov_cnt); + + /* Discard within first element */ + iov_random(&iov, &iov_cnt); + iov_tmp = iov; + iov_cnt_tmp = iov_cnt; + old_base = iov->iov_base; + size = g_test_rand_int_range(1, iov->iov_len); + ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size); + g_assert(ret == size); + g_assert(iov_tmp == iov); + g_assert(iov_cnt_tmp == iov_cnt); + g_assert(iov_tmp->iov_base == old_base + size); + iov_tmp->iov_base = old_base; /* undo before g_free() */ + iov_free(iov, iov_cnt); + + /* Discard entire first element */ + iov_random(&iov, &iov_cnt); + iov_tmp = iov; + iov_cnt_tmp = iov_cnt; + ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, iov->iov_len); + g_assert(ret == iov->iov_len); + g_assert(iov_tmp == iov + 1); + g_assert(iov_cnt_tmp == iov_cnt - 1); + iov_free(iov, iov_cnt); + + /* Discard within second element */ + iov_random(&iov, &iov_cnt); + iov_tmp = iov; + iov_cnt_tmp = iov_cnt; + old_base = iov[1].iov_base; + size = iov->iov_len + g_test_rand_int_range(1, iov[1].iov_len); + ret = iov_discard_front(&iov_tmp, &iov_cnt_tmp, size); + g_assert(ret == size); + g_assert(iov_tmp == iov + 1); + g_assert(iov_cnt_tmp == iov_cnt - 1); + g_assert(iov_tmp->iov_base == old_base + (size - iov->iov_len)); + iov_tmp->iov_base = old_base; /* undo before g_free() */ + iov_free(iov, iov_cnt); +} + +static void test_discard_back(void) +{ + struct iovec *iov; + unsigned int iov_cnt; + unsigned int iov_cnt_tmp; + void *old_base; + size_t size; + size_t ret; + + /* Discard zero bytes */ + iov_random(&iov, &iov_cnt); + iov_cnt_tmp = iov_cnt; + ret = iov_discard_back(iov, &iov_cnt_tmp, 0); + g_assert(ret == 0); + g_assert(iov_cnt_tmp == iov_cnt); + iov_free(iov, iov_cnt); + + /* Discard more bytes than vector size */ + iov_random(&iov, &iov_cnt); + iov_cnt_tmp = iov_cnt; + size = iov_size(iov, iov_cnt); + ret = iov_discard_back(iov, &iov_cnt_tmp, size + 1); + g_assert(ret == size); + g_assert(iov_cnt_tmp == 0); + iov_free(iov, iov_cnt); + + /* Discard entire vector */ + iov_random(&iov, &iov_cnt); + iov_cnt_tmp = iov_cnt; + size = iov_size(iov, iov_cnt); + ret = iov_discard_back(iov, &iov_cnt_tmp, size); + g_assert(ret == size); + g_assert(iov_cnt_tmp == 0); + iov_free(iov, iov_cnt); + + /* Discard within last element */ + iov_random(&iov, &iov_cnt); + iov_cnt_tmp = iov_cnt; + old_base = iov[iov_cnt - 1].iov_base; + size = g_test_rand_int_range(1, iov[iov_cnt - 1].iov_len); + ret = iov_discard_back(iov, &iov_cnt_tmp, size); + g_assert(ret == size); + g_assert(iov_cnt_tmp == iov_cnt); + g_assert(iov[iov_cnt - 1].iov_base == old_base); + iov_free(iov, iov_cnt); + + /* Discard entire last element */ + iov_random(&iov, &iov_cnt); + iov_cnt_tmp = iov_cnt; + old_base = iov[iov_cnt - 1].iov_base; + size = iov[iov_cnt - 1].iov_len; + ret = iov_discard_back(iov, &iov_cnt_tmp, size); + g_assert(ret == size); + g_assert(iov_cnt_tmp == iov_cnt - 1); + iov_free(iov, iov_cnt); + + /* Discard within second-to-last element */ + iov_random(&iov, &iov_cnt); + iov_cnt_tmp = iov_cnt; + old_base = iov[iov_cnt - 2].iov_base; + size = iov[iov_cnt - 1].iov_len + + g_test_rand_int_range(1, iov[iov_cnt - 2].iov_len); + ret = iov_discard_back(iov, &iov_cnt_tmp, size); + g_assert(ret == size); + g_assert(iov_cnt_tmp == iov_cnt - 1); + g_assert(iov[iov_cnt - 2].iov_base == old_base); + iov_free(iov, iov_cnt); +} + int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); g_test_rand_int(); g_test_add_func("/basic/iov/from-to-buf", test_to_from_buf); g_test_add_func("/basic/iov/io", test_io); + g_test_add_func("/basic/iov/discard-front", test_discard_front); + g_test_add_func("/basic/iov/discard-back", test_discard_back); return g_test_run(); } diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c index dc3c507f2b..5a3e82a854 100644 --- a/tests/test-qmp-commands.c +++ b/tests/test-qmp-commands.c @@ -1,8 +1,9 @@ #include <glib.h> -#include "qemu-objects.h" +#include "qemu-common.h" +#include "qapi/qmp/types.h" #include "test-qmp-commands.h" -#include "qapi/qmp-core.h" -#include "module.h" +#include "qapi/qmp/dispatch.h" +#include "qemu/module.h" #include "qapi/qmp-input-visitor.h" #include "tests/test-qapi-types.h" #include "tests/test-qapi-visit.h" diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c index f6df8cbe1e..6f68963a3d 100644 --- a/tests/test-qmp-input-strict.c +++ b/tests/test-qmp-input-strict.c @@ -14,10 +14,11 @@ #include <glib.h> #include <stdarg.h> +#include "qemu-common.h" #include "qapi/qmp-input-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" -#include "qemu-objects.h" +#include "qapi/qmp/types.h" typedef struct TestInputVisitorData { QObject *obj; diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c index 8f5a509582..955a4c0b0a 100644 --- a/tests/test-qmp-input-visitor.c +++ b/tests/test-qmp-input-visitor.c @@ -13,10 +13,11 @@ #include <glib.h> #include <stdarg.h> +#include "qemu-common.h" #include "qapi/qmp-input-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" -#include "qemu-objects.h" +#include "qapi/qmp/types.h" typedef struct TestInputVisitorData { QObject *obj; diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c index 24a6359504..71367e6efa 100644 --- a/tests/test-qmp-output-visitor.c +++ b/tests/test-qmp-output-visitor.c @@ -12,10 +12,11 @@ #include <glib.h> +#include "qemu-common.h" #include "qapi/qmp-output-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" -#include "qemu-objects.h" +#include "qapi/qmp/types.h" typedef struct TestOutputVisitorData { QmpOutputVisitor *qov; diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 5370e32041..899feda579 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -13,10 +13,11 @@ #include <glib.h> #include <stdarg.h> +#include "qemu-common.h" #include "qapi/string-input-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" -#include "qemu-objects.h" +#include "qapi/qmp/types.h" typedef struct TestInputVisitorData { StringInputVisitor *siv; diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c index 608f14a5de..79d815f888 100644 --- a/tests/test-string-output-visitor.c +++ b/tests/test-string-output-visitor.c @@ -12,10 +12,11 @@ #include <glib.h> +#include "qemu-common.h" #include "qapi/string-output-visitor.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" -#include "qemu-objects.h" +#include "qapi/qmp/types.h" typedef struct TestOutputVisitorData { StringOutputVisitor *sov; diff --git a/tests/test-thread-pool.c b/tests/test-thread-pool.c new file mode 100644 index 0000000000..9998e031f2 --- /dev/null +++ b/tests/test-thread-pool.c @@ -0,0 +1,224 @@ +#include <glib.h> +#include "qemu-common.h" +#include "block/aio.h" +#include "block/thread-pool.h" +#include "block/block.h" + +static int active; + +typedef struct { + BlockDriverAIOCB *aiocb; + int n; + int ret; +} WorkerTestData; + +static int worker_cb(void *opaque) +{ + WorkerTestData *data = opaque; + return __sync_fetch_and_add(&data->n, 1); +} + +static int long_cb(void *opaque) +{ + WorkerTestData *data = opaque; + __sync_fetch_and_add(&data->n, 1); + g_usleep(2000000); + __sync_fetch_and_add(&data->n, 1); + return 0; +} + +static void done_cb(void *opaque, int ret) +{ + WorkerTestData *data = opaque; + g_assert_cmpint(data->ret, ==, -EINPROGRESS); + data->ret = ret; + data->aiocb = NULL; + + /* Callbacks are serialized, so no need to use atomic ops. */ + active--; +} + +/* A non-blocking poll of the main AIO context (we cannot use aio_poll + * because we do not know the AioContext). + */ +static void qemu_aio_wait_nonblocking(void) +{ + qemu_notify_event(); + qemu_aio_wait(); +} + +/* Wait until all aio and bh activity has finished */ +static void qemu_aio_wait_all(void) +{ + while (qemu_aio_wait()) { + /* Do nothing */ + } +} + +static void test_submit(void) +{ + WorkerTestData data = { .n = 0 }; + thread_pool_submit(worker_cb, &data); + qemu_aio_wait_all(); + g_assert_cmpint(data.n, ==, 1); +} + +static void test_submit_aio(void) +{ + WorkerTestData data = { .n = 0, .ret = -EINPROGRESS }; + data.aiocb = thread_pool_submit_aio(worker_cb, &data, done_cb, &data); + + /* The callbacks are not called until after the first wait. */ + active = 1; + g_assert_cmpint(data.ret, ==, -EINPROGRESS); + qemu_aio_wait_all(); + g_assert_cmpint(active, ==, 0); + g_assert_cmpint(data.n, ==, 1); + g_assert_cmpint(data.ret, ==, 0); +} + +static void co_test_cb(void *opaque) +{ + WorkerTestData *data = opaque; + + active = 1; + data->n = 0; + data->ret = -EINPROGRESS; + thread_pool_submit_co(worker_cb, data); + + /* The test continues in test_submit_co, after qemu_coroutine_enter... */ + + g_assert_cmpint(data->n, ==, 1); + data->ret = 0; + active--; + + /* The test continues in test_submit_co, after qemu_aio_wait_all... */ +} + +static void test_submit_co(void) +{ + WorkerTestData data; + Coroutine *co = qemu_coroutine_create(co_test_cb); + + qemu_coroutine_enter(co, &data); + + /* Back here once the worker has started. */ + + g_assert_cmpint(active, ==, 1); + g_assert_cmpint(data.ret, ==, -EINPROGRESS); + + /* qemu_aio_wait_all will execute the rest of the coroutine. */ + + qemu_aio_wait_all(); + + /* Back here after the coroutine has finished. */ + + g_assert_cmpint(active, ==, 0); + g_assert_cmpint(data.ret, ==, 0); +} + +static void test_submit_many(void) +{ + WorkerTestData data[100]; + int i; + + /* Start more work items than there will be threads. */ + for (i = 0; i < 100; i++) { + data[i].n = 0; + data[i].ret = -EINPROGRESS; + thread_pool_submit_aio(worker_cb, &data[i], done_cb, &data[i]); + } + + active = 100; + while (active > 0) { + qemu_aio_wait(); + } + for (i = 0; i < 100; i++) { + g_assert_cmpint(data[i].n, ==, 1); + g_assert_cmpint(data[i].ret, ==, 0); + } +} + +static void test_cancel(void) +{ + WorkerTestData data[100]; + int num_canceled; + int i; + + /* Start more work items than there will be threads, to ensure + * the pool is full. + */ + test_submit_many(); + + /* Start long running jobs, to ensure we can cancel some. */ + for (i = 0; i < 100; i++) { + data[i].n = 0; + data[i].ret = -EINPROGRESS; + data[i].aiocb = thread_pool_submit_aio(long_cb, &data[i], + done_cb, &data[i]); + } + + /* Starting the threads may be left to a bottom half. Let it + * run, but do not waste too much time... + */ + active = 100; + qemu_aio_wait_nonblocking(); + + /* Wait some time for the threads to start, with some sanity + * testing on the behavior of the scheduler... + */ + g_assert_cmpint(active, ==, 100); + g_usleep(1000000); + g_assert_cmpint(active, >, 50); + + /* Cancel the jobs that haven't been started yet. */ + num_canceled = 0; + for (i = 0; i < 100; i++) { + if (__sync_val_compare_and_swap(&data[i].n, 0, 3) == 0) { + data[i].ret = -ECANCELED; + bdrv_aio_cancel(data[i].aiocb); + active--; + num_canceled++; + } + } + g_assert_cmpint(active, >, 0); + g_assert_cmpint(num_canceled, <, 100); + + /* Canceling the others will be a blocking operation. */ + for (i = 0; i < 100; i++) { + if (data[i].n != 3) { + bdrv_aio_cancel(data[i].aiocb); + } + } + + /* Finish execution and execute any remaining callbacks. */ + qemu_aio_wait_all(); + g_assert_cmpint(active, ==, 0); + for (i = 0; i < 100; i++) { + if (data[i].n == 3) { + g_assert_cmpint(data[i].ret, ==, -ECANCELED); + g_assert(data[i].aiocb != NULL); + } else { + g_assert_cmpint(data[i].n, ==, 2); + g_assert_cmpint(data[i].ret, ==, 0); + g_assert(data[i].aiocb == NULL); + } + } +} + +int main(int argc, char **argv) +{ + /* These should be removed once each AioContext has its thread pool. + * The test should create its own AioContext. + */ + qemu_init_main_loop(); + bdrv_init(); + + g_test_init(&argc, &argv, NULL); + g_test_add_func("/thread-pool/submit", test_submit); + g_test_add_func("/thread-pool/submit-aio", test_submit_aio); + g_test_add_func("/thread-pool/submit-co", test_submit_co); + g_test_add_func("/thread-pool/submit-many", test_submit_many); + g_test_add_func("/thread-pool/cancel", test_cancel); + return g_test_run(); +} diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c index b8ad16fc9e..3c6b8df607 100644 --- a/tests/test-visitor-serialization.c +++ b/tests/test-visitor-serialization.c @@ -14,9 +14,11 @@ #include <stdlib.h> #include <stdint.h> #include <float.h> + +#include "qemu-common.h" #include "test-qapi-types.h" #include "test-qapi-visit.h" -#include "qemu-objects.h" +#include "qapi/qmp/types.h" #include "qapi/qmp-input-visitor.h" #include "qapi/qmp-output-visitor.h" #include "qapi/string-input-visitor.h" |