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

fp-test-log2.c (2775B)


      1/*
      2 * fp-test-log2.c - test QEMU's softfloat log2
      3 *
      4 * Copyright (C) 2020, Linaro, Ltd.
      5 *
      6 * License: GNU GPL, version 2 or later.
      7 *   See the COPYING file in the top-level directory.
      8 */
      9#ifndef HW_POISON_H
     10#error Must define HW_POISON_H to work around TARGET_* poisoning
     11#endif
     12
     13#include "qemu/osdep.h"
     14#include "qemu/cutils.h"
     15#include <math.h>
     16#include "fpu/softfloat.h"
     17
     18typedef union {
     19    double d;
     20    float64 i;
     21} ufloat64;
     22
     23static int errors;
     24
     25static void compare(ufloat64 test, ufloat64 real, ufloat64 soft, bool exact)
     26{
     27    int msb;
     28    uint64_t ulp = UINT64_MAX;
     29
     30    if (real.i == soft.i) {
     31        return;
     32    }
     33    msb = 63 - __builtin_clzll(real.i ^ soft.i);
     34
     35    if (msb < 52) {
     36        if (real.i > soft.i) {
     37            ulp = real.i - soft.i;
     38        } else {
     39            ulp = soft.i - real.i;
     40        }
     41    }
     42
     43    /* glibc allows 3 ulp error in its libm-test-ulps; allow 4 here */
     44    if (!exact && ulp <= 4) {
     45        return;
     46    }
     47
     48    printf("test: %016" PRIx64 "  %+.13a\n"
     49           "  sf: %016" PRIx64 "  %+.13a\n"
     50           "libm: %016" PRIx64 "  %+.13a\n",
     51           test.i, test.d, soft.i, soft.d, real.i, real.d);
     52
     53    if (msb == 63) {
     54        printf("Error in sign!\n\n");
     55    } else if (msb >= 52) {
     56        printf("Error in exponent: %d\n\n",
     57               (int)(soft.i >> 52) - (int)(real.i >> 52));
     58    } else {
     59        printf("Error in fraction: %" PRIu64 " ulp\n\n", ulp);
     60    }
     61
     62    if (++errors == 20) {
     63        exit(1);
     64    }
     65}
     66
     67int main(int ac, char **av)
     68{
     69    ufloat64 test, real, soft;
     70    float_status qsf = {0};
     71    int i;
     72
     73    set_float_rounding_mode(float_round_nearest_even, &qsf);
     74
     75    test.d = 0.0;
     76    real.d = -__builtin_inf();
     77    soft.i = float64_log2(test.i, &qsf);
     78    compare(test, real, soft, true);
     79
     80    test.d = 1.0;
     81    real.d = 0.0;
     82    soft.i = float64_log2(test.i, &qsf);
     83    compare(test, real, soft, true);
     84
     85    test.d = 2.0;
     86    real.d = 1.0;
     87    soft.i = float64_log2(test.i, &qsf);
     88    compare(test, real, soft, true);
     89
     90    test.d = 4.0;
     91    real.d = 2.0;
     92    soft.i = float64_log2(test.i, &qsf);
     93    compare(test, real, soft, true);
     94
     95    test.d = 0x1p64;
     96    real.d = 64.0;
     97    soft.i = float64_log2(test.i, &qsf);
     98    compare(test, real, soft, true);
     99
    100    test.d = __builtin_inf();
    101    real.d = __builtin_inf();
    102    soft.i = float64_log2(test.i, &qsf);
    103    compare(test, real, soft, true);
    104
    105    for (i = 0; i < 10000; ++i) {
    106        test.d = drand48() + 1.0;    /* [1.0, 2.0) */
    107        real.d = log2(test.d);
    108        soft.i = float64_log2(test.i, &qsf);
    109        compare(test, real, soft, false);
    110
    111        test.d = drand48() * 100;    /* [0.0, 100) */
    112        real.d = log2(test.d);
    113        soft.i = float64_log2(test.i, &qsf);
    114        compare(test, real, soft, false);
    115    }
    116
    117    return 0;
    118}