xref: /openbmc/qemu/tests/tcg/sh4/test-macw.c (revision 05caa062)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <stdint.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 
7 int64_t mac_w(int64_t mac, const int16_t *a, const int16_t *b)
8 {
9     register uint32_t macl __asm__("macl") = mac;
10     register uint32_t mach __asm__("mach") = mac >> 32;
11 
12     asm volatile("mac.w @%0+,@%1+"
13                  : "+r"(a), "+r"(b), "+x"(macl), "+x"(mach));
14 
15     return ((uint64_t)mach << 32) | macl;
16 }
17 
18 typedef struct {
19     int64_t mac;
20     int16_t a, b;
21     int64_t res[2];
22 } Test;
23 
24 __attribute__((noinline))
25 void test(const Test *t, int sat)
26 {
27     int64_t res;
28 
29     if (sat) {
30         asm volatile("sets");
31     } else {
32         asm volatile("clrs");
33     }
34     res = mac_w(t->mac, &t->a, &t->b);
35 
36     if (res != t->res[sat]) {
37         fprintf(stderr, "%#llx + (%#x * %#x) = %#llx -- got %#llx\n",
38                 t->mac, t->a, t->b, t->res[sat], res);
39         abort();
40     }
41 }
42 
43 int main()
44 {
45     static const Test tests[] = {
46         { 0, 2, 3, { 6, 6 } },
47         { 0x123456787ffffffell, 2, -3,
48           { 0x123456787ffffff8ll, 0x123456787ffffff8ll } },
49         { 0xabcdef127ffffffall, 2, 3,
50           { 0xabcdef1280000000ll, 0x000000017fffffffll } },
51         { 0xfffffffffll, INT16_MAX, INT16_MAX,
52           { 0x103fff0000ll, 0xf3fff0000ll } },
53     };
54 
55     for (int i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) {
56         for (int j = 0; j < 2; ++j) {
57             test(&tests[i], j);
58         }
59     }
60     return 0;
61 }
62