cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

test-int128.c (7053B)


      1/*
      2 * Test Int128 arithmetic
      3 *
      4 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
      5 * See the COPYING.LIB file in the top-level directory.
      6 *
      7 */
      8
      9#include "qemu/osdep.h"
     10#include "qemu/int128.h"
     11
     12/* clang doesn't support __noclone__ but it does have a mechanism for
     13 * telling us this. We assume that if we don't have __has_attribute()
     14 * then this is GCC and that GCC always supports __noclone__.
     15 */
     16#if defined(__has_attribute)
     17#if !__has_attribute(__noclone__)
     18#define ATTRIBUTE_NOCLONE
     19#endif
     20#endif
     21#ifndef ATTRIBUTE_NOCLONE
     22#define ATTRIBUTE_NOCLONE __attribute__((__noclone__))
     23#endif
     24
     25static uint32_t tests[8] = {
     26    0x00000000, 0x00000001, 0x7FFFFFFE, 0x7FFFFFFF,
     27    0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF,
     28};
     29
     30#define LOW    3ULL
     31#define HIGH   (1ULL << 63)
     32#define MIDDLE (-1ULL & ~LOW & ~HIGH)
     33
     34static uint64_t expand16(unsigned x)
     35{
     36    return (x & LOW) | ((x & 4) ? MIDDLE : 0) | (x & 0x8000 ? HIGH : 0);
     37}
     38
     39static Int128 expand(uint32_t x)
     40{
     41    uint64_t l, h;
     42    l = expand16(x & 65535);
     43    h = expand16(x >> 16);
     44    return (Int128) int128_make128(l, h);
     45};
     46
     47static void test_and(void)
     48{
     49    int i, j;
     50
     51    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
     52        for (j = 0; j < ARRAY_SIZE(tests); ++j) {
     53            Int128 a = expand(tests[i]);
     54            Int128 b = expand(tests[j]);
     55            Int128 r = expand(tests[i] & tests[j]);
     56            Int128 s = int128_and(a, b);
     57            g_assert_cmpuint(int128_getlo(r), ==, int128_getlo(s));
     58            g_assert_cmpuint(int128_gethi(r), ==, int128_gethi(s));
     59        }
     60    }
     61}
     62
     63static void test_add(void)
     64{
     65    int i, j;
     66
     67    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
     68        for (j = 0; j < ARRAY_SIZE(tests); ++j) {
     69            Int128 a = expand(tests[i]);
     70            Int128 b = expand(tests[j]);
     71            Int128 r = expand(tests[i] + tests[j]);
     72            Int128 s = int128_add(a, b);
     73            g_assert_cmpuint(int128_getlo(r), ==, int128_getlo(s));
     74            g_assert_cmpuint(int128_gethi(r), ==, int128_gethi(s));
     75        }
     76    }
     77}
     78
     79static void test_sub(void)
     80{
     81    int i, j;
     82
     83    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
     84        for (j = 0; j < ARRAY_SIZE(tests); ++j) {
     85            Int128 a = expand(tests[i]);
     86            Int128 b = expand(tests[j]);
     87            Int128 r = expand(tests[i] - tests[j]);
     88            Int128 s = int128_sub(a, b);
     89            g_assert_cmpuint(int128_getlo(r), ==, int128_getlo(s));
     90            g_assert_cmpuint(int128_gethi(r), ==, int128_gethi(s));
     91        }
     92    }
     93}
     94
     95static void test_neg(void)
     96{
     97    int i;
     98
     99    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
    100        Int128 a = expand(tests[i]);
    101        Int128 r = expand(-tests[i]);
    102        Int128 s = int128_neg(a);
    103        g_assert_cmpuint(int128_getlo(r), ==, int128_getlo(s));
    104        g_assert_cmpuint(int128_gethi(r), ==, int128_gethi(s));
    105    }
    106}
    107
    108static void test_nz(void)
    109{
    110    int i, j;
    111
    112    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
    113        for (j = 0; j < ARRAY_SIZE(tests); ++j) {
    114            Int128 a = expand(tests[i]);
    115            g_assert_cmpuint(int128_nz(a), ==, tests[i] != 0);
    116        }
    117    }
    118}
    119
    120static void test_le(void)
    121{
    122    int i, j;
    123
    124    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
    125        for (j = 0; j < ARRAY_SIZE(tests); ++j) {
    126            /* Signed comparison */
    127            int32_t a = (int32_t) tests[i];
    128            int32_t b = (int32_t) tests[j];
    129            g_assert_cmpuint(int128_le(expand(a), expand(b)), ==, a <= b);
    130        }
    131    }
    132}
    133
    134static void test_lt(void)
    135{
    136    int i, j;
    137
    138    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
    139        for (j = 0; j < ARRAY_SIZE(tests); ++j) {
    140            /* Signed comparison */
    141            int32_t a = (int32_t) tests[i];
    142            int32_t b = (int32_t) tests[j];
    143            g_assert_cmpuint(int128_lt(expand(a), expand(b)), ==, a < b);
    144        }
    145    }
    146}
    147
    148static void test_ge(void)
    149{
    150    int i, j;
    151
    152    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
    153        for (j = 0; j < ARRAY_SIZE(tests); ++j) {
    154            /* Signed comparison */
    155            int32_t a = (int32_t) tests[i];
    156            int32_t b = (int32_t) tests[j];
    157            g_assert_cmpuint(int128_ge(expand(a), expand(b)), ==, a >= b);
    158        }
    159    }
    160}
    161
    162static void test_gt(void)
    163{
    164    int i, j;
    165
    166    for (i = 0; i < ARRAY_SIZE(tests); ++i) {
    167        for (j = 0; j < ARRAY_SIZE(tests); ++j) {
    168            /* Signed comparison */
    169            int32_t a = (int32_t) tests[i];
    170            int32_t b = (int32_t) tests[j];
    171            g_assert_cmpuint(int128_gt(expand(a), expand(b)), ==, a > b);
    172        }
    173    }
    174}
    175
    176/* Make sure to test undefined behavior at runtime! */
    177
    178static void __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
    179test_rshift_one(uint32_t x, int n, uint64_t h, uint64_t l)
    180{
    181    Int128 a = expand(x);
    182    Int128 r = int128_rshift(a, n);
    183    g_assert_cmpuint(int128_getlo(r), ==, l);
    184    g_assert_cmpuint(int128_gethi(r), ==, h);
    185}
    186
    187static void test_rshift(void)
    188{
    189    test_rshift_one(0x00010000U, 64, 0x0000000000000000ULL, 0x0000000000000001ULL);
    190    test_rshift_one(0x80010000U, 64, 0xFFFFFFFFFFFFFFFFULL, 0x8000000000000001ULL);
    191    test_rshift_one(0x7FFE0000U, 64, 0x0000000000000000ULL, 0x7FFFFFFFFFFFFFFEULL);
    192    test_rshift_one(0xFFFE0000U, 64, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL);
    193    test_rshift_one(0x00010000U, 60, 0x0000000000000000ULL, 0x0000000000000010ULL);
    194    test_rshift_one(0x80010000U, 60, 0xFFFFFFFFFFFFFFF8ULL, 0x0000000000000010ULL);
    195    test_rshift_one(0x00018000U, 60, 0x0000000000000000ULL, 0x0000000000000018ULL);
    196    test_rshift_one(0x80018000U, 60, 0xFFFFFFFFFFFFFFF8ULL, 0x0000000000000018ULL);
    197    test_rshift_one(0x7FFE0000U, 60, 0x0000000000000007ULL, 0xFFFFFFFFFFFFFFE0ULL);
    198    test_rshift_one(0xFFFE0000U, 60, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFE0ULL);
    199    test_rshift_one(0x7FFE8000U, 60, 0x0000000000000007ULL, 0xFFFFFFFFFFFFFFE8ULL);
    200    test_rshift_one(0xFFFE8000U, 60, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFE8ULL);
    201    test_rshift_one(0x00018000U,  0, 0x0000000000000001ULL, 0x8000000000000000ULL);
    202    test_rshift_one(0x80018000U,  0, 0x8000000000000001ULL, 0x8000000000000000ULL);
    203    test_rshift_one(0x7FFE0000U,  0, 0x7FFFFFFFFFFFFFFEULL, 0x0000000000000000ULL);
    204    test_rshift_one(0xFFFE0000U,  0, 0xFFFFFFFFFFFFFFFEULL, 0x0000000000000000ULL);
    205    test_rshift_one(0x7FFE8000U,  0, 0x7FFFFFFFFFFFFFFEULL, 0x8000000000000000ULL);
    206    test_rshift_one(0xFFFE8000U,  0, 0xFFFFFFFFFFFFFFFEULL, 0x8000000000000000ULL);
    207}
    208
    209int main(int argc, char **argv)
    210{
    211    g_test_init(&argc, &argv, NULL);
    212    g_test_add_func("/int128/int128_and", test_and);
    213    g_test_add_func("/int128/int128_add", test_add);
    214    g_test_add_func("/int128/int128_sub", test_sub);
    215    g_test_add_func("/int128/int128_neg", test_neg);
    216    g_test_add_func("/int128/int128_nz", test_nz);
    217    g_test_add_func("/int128/int128_le", test_le);
    218    g_test_add_func("/int128/int128_lt", test_lt);
    219    g_test_add_func("/int128/int128_ge", test_ge);
    220    g_test_add_func("/int128/int128_gt", test_gt);
    221    g_test_add_func("/int128/int128_rshift", test_rshift);
    222    return g_test_run();
    223}