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-i386-fscale.c (3583B)


      1/* Test fscale instruction.  */
      2
      3#include <stdint.h>
      4#include <stdio.h>
      5
      6union u {
      7    struct { uint64_t sig; uint16_t sign_exp; } s;
      8    long double ld;
      9};
     10
     11volatile long double ld_third = 1.0L / 3.0L;
     12volatile long double ld_four_thirds = 4.0L / 3.0L;
     13volatile union u ld_invalid_1 = { .s = { 1, 1234 } };
     14volatile union u ld_invalid_2 = { .s = { 0, 1234 } };
     15volatile union u ld_invalid_3 = { .s = { 0, 0x7fff } };
     16volatile union u ld_invalid_4 = { .s = { (UINT64_C(1) << 63) - 1, 0x7fff } };
     17
     18volatile long double ld_res;
     19
     20int isnan_ld(long double x)
     21{
     22  union u tmp = { .ld = x };
     23  return ((tmp.s.sign_exp & 0x7fff) == 0x7fff &&
     24          (tmp.s.sig >> 63) != 0 &&
     25          (tmp.s.sig << 1) != 0);
     26}
     27
     28int issignaling_ld(long double x)
     29{
     30    union u tmp = { .ld = x };
     31    return isnan_ld(x) && (tmp.s.sig & UINT64_C(0x4000000000000000)) == 0;
     32}
     33
     34int main(void)
     35{
     36    short cw;
     37    int ret = 0;
     38    __asm__ volatile ("fscale" : "=t" (ld_res) :
     39                      "0" (2.5L), "u" (__builtin_nansl("")));
     40    if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) {
     41        printf("FAIL: fscale snan\n");
     42        ret = 1;
     43    }
     44    __asm__ volatile ("fscale" : "=t" (ld_res) :
     45                      "0" (2.5L), "u" (ld_invalid_1.ld));
     46    if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) {
     47        printf("FAIL: fscale invalid 1\n");
     48        ret = 1;
     49    }
     50    __asm__ volatile ("fscale" : "=t" (ld_res) :
     51                      "0" (2.5L), "u" (ld_invalid_2.ld));
     52    if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) {
     53        printf("FAIL: fscale invalid 2\n");
     54        ret = 1;
     55    }
     56    __asm__ volatile ("fscale" : "=t" (ld_res) :
     57                      "0" (2.5L), "u" (ld_invalid_3.ld));
     58    if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) {
     59        printf("FAIL: fscale invalid 3\n");
     60        ret = 1;
     61    }
     62    __asm__ volatile ("fscale" : "=t" (ld_res) :
     63                      "0" (2.5L), "u" (ld_invalid_4.ld));
     64    if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) {
     65        printf("FAIL: fscale invalid 4\n");
     66        ret = 1;
     67    }
     68    __asm__ volatile ("fscale" : "=t" (ld_res) :
     69                      "0" (0.0L), "u" (__builtin_infl()));
     70    if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) {
     71        printf("FAIL: fscale 0 up inf\n");
     72        ret = 1;
     73    }
     74    __asm__ volatile ("fscale" : "=t" (ld_res) :
     75                      "0" (__builtin_infl()), "u" (-__builtin_infl()));
     76    if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) {
     77        printf("FAIL: fscale inf down inf\n");
     78        ret = 1;
     79    }
     80    /* Set round-downward.  */
     81    __asm__ volatile ("fnstcw %0" : "=m" (cw));
     82    cw = (cw & ~0xc00) | 0x400;
     83    __asm__ volatile ("fldcw %0" : : "m" (cw));
     84    __asm__ volatile ("fscale" : "=t" (ld_res) :
     85                      "0" (1.0L), "u" (__builtin_infl()));
     86    if (ld_res != __builtin_infl()) {
     87        printf("FAIL: fscale finite up inf\n");
     88        ret = 1;
     89    }
     90    __asm__ volatile ("fscale" : "=t" (ld_res) :
     91                      "0" (-1.0L), "u" (-__builtin_infl()));
     92    if (ld_res != -0.0L || __builtin_copysignl(1.0L, ld_res) != -1.0L) {
     93        printf("FAIL: fscale finite down inf\n");
     94        ret = 1;
     95    }
     96    /* Set round-to-nearest with single-precision rounding.  */
     97    cw = cw & ~0xf00;
     98    __asm__ volatile ("fldcw %0" : : "m" (cw));
     99    __asm__ volatile ("fscale" : "=t" (ld_res) :
    100                      "0" (ld_third), "u" (2.0L));
    101    cw = cw | 0x300;
    102    __asm__ volatile ("fldcw %0" : : "m" (cw));
    103    if (ld_res != ld_four_thirds) {
    104        printf("FAIL: fscale single-precision\n");
    105        ret = 1;
    106    }
    107    return ret;
    108}