Add a mips32r6el-linux-user target running, on mips32r6-generic, 32-bit versions of the Release 6 tests that don't need 64-bit registers, starting with and, nor, or and xor. Output is TAP.
Signed-off-by: Philippe Mathieu-Daudé <[email protected]> --- tests/tcg/mips/include/wrappers_mips32r6.h | 61 ++++++++++++++++++++++ tests/tcg/mipsel/test_mips32r6_logic.c | 60 +++++++++++++++++++++ tests/tcg/mipsel/meson.build | 29 ++++++++++ 3 files changed, 150 insertions(+) create mode 100644 tests/tcg/mips/include/wrappers_mips32r6.h create mode 100644 tests/tcg/mipsel/test_mips32r6_logic.c diff --git a/tests/tcg/mips/include/wrappers_mips32r6.h b/tests/tcg/mips/include/wrappers_mips32r6.h new file mode 100644 index 000000000000..316aa69ef582 --- /dev/null +++ b/tests/tcg/mips/include/wrappers_mips32r6.h @@ -0,0 +1,61 @@ +/* + * Wrappers for MIPS32R6 instructions operating on 32-bit values + * (32-bit counterpart of wrappers_mips64r6.h). + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef WRAPPERS_MIPS32R6_H +#define WRAPPERS_MIPS32R6_H + +#include <stdint.h> + +#define DO_MIPS32R6__RD__RS(suffix, mnemonic) \ +static inline void do_mips32r6_##suffix(const uint32_t *input, \ + uint32_t *output) \ +{ \ + __asm__ volatile ( \ + "lw $t1, 0(%0)\n\t" \ + #mnemonic " $t0, $t1\n\t" \ + "sw $t0, 0(%1)\n\t" \ + : \ + : "r" (input), "r" (output) \ + : "t0", "t1", "memory" \ + ); \ +} + +#define DO_MIPS32R6__RD__RS_RT(suffix, mnemonic) \ +static inline void do_mips32r6_##suffix(const uint32_t *input1, \ + const uint32_t *input2, \ + uint32_t *output) \ +{ \ + __asm__ volatile ( \ + "lw $t1, 0(%0)\n\t" \ + "lw $t2, 0(%1)\n\t" \ + #mnemonic " $t0, $t1, $t2\n\t" \ + "sw $t0, 0(%2)\n\t" \ + : \ + : "r" (input1), "r" (input2), "r" (output) \ + : "t0", "t1", "t2", "memory" \ + ); \ +} + +DO_MIPS32R6__RD__RS(CLO, clo) +DO_MIPS32R6__RD__RS(CLZ, clz) +DO_MIPS32R6__RD__RS(BITSWAP, bitswap) + +DO_MIPS32R6__RD__RS_RT(SLLV, sllv) +DO_MIPS32R6__RD__RS_RT(SRLV, srlv) +DO_MIPS32R6__RD__RS_RT(SRAV, srav) + +DO_MIPS32R6__RD__RS_RT(MUL, mul) +DO_MIPS32R6__RD__RS_RT(MUH, muh) +DO_MIPS32R6__RD__RS_RT(MULU, mulu) +DO_MIPS32R6__RD__RS_RT(MUHU, muhu) + +DO_MIPS32R6__RD__RS_RT(AND, and) +DO_MIPS32R6__RD__RS_RT(NOR, nor) +DO_MIPS32R6__RD__RS_RT(OR, or) +DO_MIPS32R6__RD__RS_RT(XOR, xor) + +#endif diff --git a/tests/tcg/mipsel/test_mips32r6_logic.c b/tests/tcg/mipsel/test_mips32r6_logic.c new file mode 100644 index 000000000000..b640aa0975b5 --- /dev/null +++ b/tests/tcg/mipsel/test_mips32r6_logic.c @@ -0,0 +1,60 @@ +/* + * MIPS32R6 tests: logical instructions + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <stdint.h> + +#include "../include/tap.h" +#include "../mips/include/wrappers_mips32r6.h" +#include "../mips/include/test_inputs_32.h" + +typedef void (*binary_op_32)(const uint32_t *, const uint32_t *, uint32_t *); +typedef uint32_t (*ref_op_32)(uint32_t, uint32_t); + +static uint32_t ref_and(uint32_t a, uint32_t b) { return a & b; } +static uint32_t ref_nor(uint32_t a, uint32_t b) { return ~(a | b); } +static uint32_t ref_or(uint32_t a, uint32_t b) { return a | b; } +static uint32_t ref_xor(uint32_t a, uint32_t b) { return a ^ b; } + +static int check_op(const char *name, binary_op_32 op, ref_op_32 ref, + const uint32_t *input, size_t count) +{ + int fail = 0; + + for (size_t i = 0; i < count; i++) { + for (size_t j = 0; j < count; j++) { + uint32_t a = input[i], b = input[j], res = 0; + + op(&a, &b, &res); + if (res != ref(a, b)) { + TAP_INFO("%s: %08x, %08x: got %08x expected %08x", + name, a, b, res, ref(a, b)); + fail = 1; + } + } + } + return fail; +} + +static int run(const char *name, binary_op_32 op, ref_op_32 ref) +{ + int ret = 0; + + ret |= check_op(name, op, ref, b32_pattern, PATTERN_INPUTS_32_SHORT_COUNT); + ret |= check_op(name, op, ref, b32_random, RANDOM_INPUTS_32_SHORT_COUNT); + tap_report(!ret, "MIPS32R6 logic %s", name); + return ret; +} + +int main(void) +{ + TAP_START(); + run("AND", do_mips32r6_AND, ref_and); + run("NOR", do_mips32r6_NOR, ref_nor); + run("OR", do_mips32r6_OR, ref_or); + run("XOR", do_mips32r6_XOR, ref_xor); + + return tap_done(); +} diff --git a/tests/tcg/mipsel/meson.build b/tests/tcg/mipsel/meson.build index 1951c3c437fb..d64cf50f5a05 100644 --- a/tests/tcg/mipsel/meson.build +++ b/tests/tcg/mipsel/meson.build @@ -63,3 +63,32 @@ if 'qemu-mipsel' in emulators } } endif + +tests = [] + +tests_mips32r6 = [ + 'test_mips32r6_logic.c', +] + +foreach src: tests_mips32r6 + tests += { + src: { + 'cflags': ['-mabi=32', '-march=mips32r6'], + 'qemu_args': ['-cpu', 'mips32r6-generic'], + 'protocol': 'tap', + } + } +endforeach + +if 'qemu-mipsel' in emulators + tcg_tests += { + 'mips32r6el-linux-user': { + 'cc': 'mipsisa32r6el-linux-gnu-gcc', + 'cc_dockerfile': 'debian-all-test-cross', + 'folder': 'mipsel', + 'gdb_arch': 'mipsel', + 'qemu': emulators['qemu-mipsel'], + 'tests': tests, + } + } +endif -- 2.55.0
