|
| 1 | +#include <assert.h> |
| 2 | +#include <limits.h> |
| 3 | +#include <unistd.h> |
| 4 | +#include <signal.h> |
| 5 | +#include <stdint.h> |
| 6 | + |
| 7 | +#define XSTR(x) #x |
| 8 | +#define STR(x) XSTR(x) |
| 9 | +#define I128(a, b) ((__int128)(a) << 64 | (b)) |
| 10 | + |
| 11 | +#define TEST(INSN, A, B, EXP) \ |
| 12 | + do { \ |
| 13 | + __uint128_t a = I128(A, 0); \ |
| 14 | + __uint128_t b = I128(B, 0); \ |
| 15 | + __uint128_t t; \ |
| 16 | + \ |
| 17 | + asm(INSN " %0, %1, %2\n\t" : "=wa"(t) : "wa"(a), "wa"(b)); \ |
| 18 | + \ |
| 19 | + assert(t == I128(EXP, 0)); \ |
| 20 | + } while (0) |
| 21 | + |
| 22 | +static inline void test_nan() |
| 23 | +{ |
| 24 | + TEST("xsmaxcdp", 0x42ULL, 0x7FF0000000000001ULL, 0x7FF0000000000001ULL); |
| 25 | + TEST("xsmaxcdp", 0x7FF0000000000001ULL, 0x42ULL, 0x42ULL); |
| 26 | + |
| 27 | + TEST("xsmaxcdp", 0x42ULL, 0x7FFF000000000000ULL, 0x7FFF000000000000ULL); |
| 28 | + TEST("xsmaxcdp", 0x7FFF000000000000ULL, 0x42ULL, 0x42ULL); |
| 29 | + |
| 30 | + TEST("xsmaxcdp", 0x42ULL, 0x7FF8000000000000ULL, 0x7FF8000000000000ULL); |
| 31 | + TEST("xsmaxcdp", 0x7FF8000000000000ULL, 0x42ULL, 0x42ULL); |
| 32 | + |
| 33 | + TEST("xsmincdp", 0x42ULL, 0x7FF0000000000001ULL, 0x7FF0000000000001ULL); |
| 34 | + TEST("xsmincdp", 0x7FF0000000000001ULL, 0x42ULL, 0x42ULL); |
| 35 | + |
| 36 | + TEST("xsmincdp", 0x42ULL, 0x7FFF000000000000ULL, 0x7FFF000000000000ULL); |
| 37 | + TEST("xsmincdp", 0x7FFF000000000000ULL, 0x42ULL, 0x42ULL); |
| 38 | + |
| 39 | + TEST("xsmincdp", 0x42ULL, 0x7FF8000000000000ULL, 0x7FF8000000000000ULL); |
| 40 | + TEST("xsmincdp", 0x7FF8000000000000ULL, 0x42ULL, 0x42ULL); |
| 41 | + |
| 42 | + TEST("xsmaxjdp", 0x42ULL, 0x7FF0000000000001ULL, 0x7FF0000000000001ULL); |
| 43 | + TEST("xsmaxjdp", 0x7FF0000000000001ULL, 0x42ULL, 0x7FF0000000000001ULL); |
| 44 | + TEST("xsmaxjdp", 0x7FF8000000000000ULL, 0x7FF0000000000001ULL, |
| 45 | + 0x7FF8000000000000ULL); |
| 46 | + TEST("xsmaxjdp", 0x7FF0000000000001ULL, 0x7FF8000000000000ULL, |
| 47 | + 0x7FF0000000000001ULL); |
| 48 | + |
| 49 | + TEST("xsminjdp", 0x42ULL, 0x7FF0000000000001ULL, 0x7FF0000000000001ULL); |
| 50 | + TEST("xsminjdp", 0x7FF0000000000001ULL, 0x42ULL, 0x7FF0000000000001ULL); |
| 51 | + TEST("xsminjdp", 0x7FF8000000000000ULL, 0x7FF0000000000001ULL, |
| 52 | + 0x7FF8000000000000ULL); |
| 53 | + TEST("xsminjdp", 0x7FF0000000000001ULL, 0x7FF8000000000000ULL, |
| 54 | + 0x7FF0000000000001ULL); |
| 55 | +} |
| 56 | + |
| 57 | +static inline void test_general_case() |
| 58 | +{ |
| 59 | + TEST("xsmaxcdp", 0xad53f789, 0xbeaab9c5, 0xbeaab9c5); |
| 60 | + TEST("xsmaxcdp", 0x8600dd9ea0, 0x4b9f8cffd7, 0x8600dd9ea0); |
| 61 | + |
| 62 | + TEST("xsmincdp", 0xad53f789, 0xbeaab9c5, 0xad53f789); |
| 63 | + TEST("xsmincdp", 0x8600dd9ea0, 0x4b9f8cffd7, 0x4b9f8cffd7); |
| 64 | + |
| 65 | + TEST("xsmaxjdp", 0xad53f789, 0xbeaab9c5, 0xbeaab9c5); |
| 66 | + TEST("xsmaxjdp", 0x8600dd9ea0, 0x4b9f8cffd7, 0x8600dd9ea0); |
| 67 | + |
| 68 | + TEST("xsminjdp", 0xad53f789, 0xbeaab9c5, 0xad53f789); |
| 69 | + TEST("xsminjdp", 0x8600dd9ea0, 0x4b9f8cffd7, 0x4b9f8cffd7); |
| 70 | +} |
| 71 | + |
| 72 | +int main(void) |
| 73 | +{ |
| 74 | + struct sigaction action; |
| 75 | + |
| 76 | + action.sa_handler = _exit; |
| 77 | + sigaction(SIGABRT, &action, NULL); |
| 78 | + |
| 79 | + test_nan(); |
| 80 | + test_general_case(); |
| 81 | + |
| 82 | + return 0; |
| 83 | +} |
0 commit comments