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

float_madds.c (2225B)


      1/*
      2 * Fused Multiply Add (Single)
      3 *
      4 * Copyright (c) 2019 Linaro
      5 *
      6 * SPDX-License-Identifier: GPL-3.0-or-later
      7 */
      8
      9#include <stdio.h>
     10#include <stdlib.h>
     11#include <math.h>
     12#include <float.h>
     13#include <fenv.h>
     14
     15#include "float_helpers.h"
     16
     17#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
     18
     19typedef struct {
     20    int flag;
     21    char *desc;
     22} float_mapping;
     23
     24float_mapping round_flags[] = {
     25    { FE_TONEAREST, "to nearest" },
     26#ifdef FE_UPWARD
     27    { FE_UPWARD, "upwards" },
     28#endif
     29#ifdef FE_DOWNWARD
     30    { FE_DOWNWARD, "downwards" },
     31#endif
     32#ifdef FE_TOWARDZERO
     33    { FE_TOWARDZERO, "to zero" }
     34#endif
     35};
     36
     37
     38static void print_inputs(float a, float b, float c)
     39{
     40    char *a_fmt, *b_fmt, *c_fmt;
     41
     42    a_fmt = fmt_f32(a);
     43    b_fmt = fmt_f32(b);
     44    c_fmt = fmt_f32(c);
     45
     46    printf("op : %s * %s + %s\n", a_fmt, b_fmt, c_fmt);
     47
     48    free(a_fmt);
     49    free(b_fmt);
     50    free(c_fmt);
     51}
     52
     53static void print_result(float r, int j, int k)
     54{
     55    char *r_fmt, *flag_fmt;
     56
     57    r_fmt = fmt_f32(r);
     58    flag_fmt = fmt_flags();
     59
     60    printf("res: %s flags=%s (%d/%d)\n", r_fmt, flag_fmt, j, k);
     61
     62    free(r_fmt);
     63    free(flag_fmt);
     64}
     65
     66static void do_madds(float a, float b, float c, int j, int k)
     67{
     68    float r;
     69
     70    print_inputs(a, b, c);
     71
     72    feclearexcept(FE_ALL_EXCEPT);
     73    r = __builtin_fmaf(a, b, c);
     74
     75    print_result(r, j, k);
     76}
     77
     78int main(int argc, char *argv[argc])
     79{
     80    int i, j, k, nums = get_num_f32();
     81    float a, b, c;
     82
     83    for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
     84        if (fesetround(round_flags[i].flag) != 0) {
     85            printf("### Rounding %s skipped\n", round_flags[i].desc);
     86            continue;
     87        }
     88        printf("### Rounding %s\n", round_flags[i].desc);
     89        for (j = 0; j < nums; j++) {
     90            for (k = 0; k < 3; k++) {
     91                a = get_f32(j + ((k)%3));
     92                b = get_f32(j + ((k+1)%3));
     93                c = get_f32(j + ((k+2)%3));
     94                do_madds(a, b, c, j, k);
     95            }
     96        }
     97
     98        /* From https://bugs.launchpad.net/qemu/+bug/1841491 */
     99        printf("# LP184149\n");
    100        do_madds(0x1.ffffffffffffcp-1022, 0x1.0000000000001p-1, 0x0.0000000000001p-1022, j, 0);
    101        do_madds(0x8p-152, 0x8p-152, 0x8p-152, j+1, 0);
    102    }
    103
    104    return 0;
    105}