1*c97e8977SZack Buhman /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*c97e8977SZack Buhman 3*c97e8977SZack Buhman #include <stdint.h> 4*c97e8977SZack Buhman #include <stdlib.h> 5*c97e8977SZack Buhman #include <stdio.h> 6*c97e8977SZack Buhman 7*c97e8977SZack Buhman #define MACL_S_MIN (-(1ll << 47)) 8*c97e8977SZack Buhman #define MACL_S_MAX ((1ll << 47) - 1) 9*c97e8977SZack Buhman 10*c97e8977SZack Buhman int64_t mac_l(int64_t mac, const int32_t *a, const int32_t *b) 11*c97e8977SZack Buhman { 12*c97e8977SZack Buhman register uint32_t macl __asm__("macl") = mac; 13*c97e8977SZack Buhman register uint32_t mach __asm__("mach") = mac >> 32; 14*c97e8977SZack Buhman 15*c97e8977SZack Buhman asm volatile("mac.l @%0+,@%1+" 16*c97e8977SZack Buhman : "+r"(a), "+r"(b), "+x"(macl), "+x"(mach)); 17*c97e8977SZack Buhman 18*c97e8977SZack Buhman return ((uint64_t)mach << 32) | macl; 19*c97e8977SZack Buhman } 20*c97e8977SZack Buhman 21*c97e8977SZack Buhman typedef struct { 22*c97e8977SZack Buhman int64_t mac; 23*c97e8977SZack Buhman int32_t a, b; 24*c97e8977SZack Buhman int64_t res[2]; 25*c97e8977SZack Buhman } Test; 26*c97e8977SZack Buhman 27*c97e8977SZack Buhman __attribute__((noinline)) 28*c97e8977SZack Buhman void test(const Test *t, int sat) 29*c97e8977SZack Buhman { 30*c97e8977SZack Buhman int64_t res; 31*c97e8977SZack Buhman 32*c97e8977SZack Buhman if (sat) { 33*c97e8977SZack Buhman asm volatile("sets"); 34*c97e8977SZack Buhman } else { 35*c97e8977SZack Buhman asm volatile("clrs"); 36*c97e8977SZack Buhman } 37*c97e8977SZack Buhman res = mac_l(t->mac, &t->a, &t->b); 38*c97e8977SZack Buhman 39*c97e8977SZack Buhman if (res != t->res[sat]) { 40*c97e8977SZack Buhman fprintf(stderr, "%#llx + (%#x * %#x) = %#llx -- got %#llx\n", 41*c97e8977SZack Buhman t->mac, t->a, t->b, t->res[sat], res); 42*c97e8977SZack Buhman abort(); 43*c97e8977SZack Buhman } 44*c97e8977SZack Buhman } 45*c97e8977SZack Buhman 46*c97e8977SZack Buhman int main() 47*c97e8977SZack Buhman { 48*c97e8977SZack Buhman static const Test tests[] = { 49*c97e8977SZack Buhman { 0x00007fff12345678ll, INT32_MAX, INT32_MAX, 50*c97e8977SZack Buhman { 0x40007ffe12345679ll, MACL_S_MAX } }, 51*c97e8977SZack Buhman { MACL_S_MIN, -1, 1, 52*c97e8977SZack Buhman { 0xffff7fffffffffffll, MACL_S_MIN } }, 53*c97e8977SZack Buhman { INT64_MIN, -1, 1, 54*c97e8977SZack Buhman { INT64_MAX, MACL_S_MIN } }, 55*c97e8977SZack Buhman { 0x00007fff00000000ll, INT32_MAX, INT32_MAX, 56*c97e8977SZack Buhman { 0x40007ffe00000001ll, MACL_S_MAX } }, 57*c97e8977SZack Buhman { 4, 1, 2, { 6, 6 } }, 58*c97e8977SZack Buhman { -4, -1, -2, { -2, -2 } }, 59*c97e8977SZack Buhman }; 60*c97e8977SZack Buhman 61*c97e8977SZack Buhman for (int i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { 62*c97e8977SZack Buhman for (int j = 0; j < 2; ++j) { 63*c97e8977SZack Buhman test(&tests[i], j); 64*c97e8977SZack Buhman } 65*c97e8977SZack Buhman } 66*c97e8977SZack Buhman return 0; 67*c97e8977SZack Buhman } 68