Home | History | Annotate | Download | only in s390x
      1 #include <assert.h>
      2 #include <stdlib.h>
      3 #include <stdio.h>
      4 #include <stdint.h>
      5 #include <inttypes.h>
      6 #include "opcodes.h"
      7 #include "rounding.h"
      8 
      9 /* Test "fixbr"  with rounding mode given in insn (m3 field)
     10    Covers all generally available rounding modes that can be mapped to
     11    IRRoundingMode. As a consequence m3=1 which is "round to nearest with
     12    ties away from 0" is not tested here.
     13 */
     14 
     15 const char *
     16 rtext(unsigned m3_round)
     17 {
     18    switch (m3_round) {
     19    case 0: return "[-> per fpc]";
     20    case 1: return "[-> nearest away]";
     21    case 3: return "[-> prepare short]";   // floating point extension fac needed
     22    case 4: return "[-> nearest even]";
     23    case 5: return "[-> 0]";
     24    case 6: return "[-> +inf]";
     25    case 7: return "[-> -inf]";
     26    }
     27    assert(0);
     28 }
     29 
     30 #define round_to_int(value,round)                             \
     31 do {                                                          \
     32    long double src = value;                                   \
     33    long double dst;                                           \
     34                                                               \
     35    __asm__ volatile ("fixbr %[dst]," #round ",%[src]\n\t"     \
     36                      : [dst] "=f"(dst)                        \
     37                      : [src] "f"(src));                       \
     38                                                               \
     39    printf("fixbr %.5Lf\t-> %Lg  %s\n",                        \
     40           src, dst, rtext(round));                            \
     41 } while (0)
     42 
     43 #define fixbr(value,round) round_to_int(value,round)
     44 
     45 void
     46 set_rounding_mode(unsigned mode)
     47 {
     48    register unsigned r asm("1") = mode;
     49    __asm__ volatile ( SFPC(1) : : "d"(r) );
     50 }
     51 
     52 
     53 int main(void)
     54 {
     55    int j;
     56    static const long double dval[] = {
     57       1.25, 1.5, 2.5, 1.75, -1.25, -1.5, -2.5, -1.75, 0.0,
     58    };
     59 
     60    assert(sizeof(long double) == 16);
     61 
     62    /* f128 -> f128, round to int */
     63    for (j = 0; j < sizeof dval / sizeof dval[0]; ++j) {
     64       set_rounding_mode(FPC_BFP_ROUND_ZERO);
     65       fixbr(dval[j], M3_BFP_ROUND_NEAREST_EVEN);
     66       set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN);
     67       fixbr(dval[j], M3_BFP_ROUND_ZERO);
     68       fixbr(dval[j], M3_BFP_ROUND_POSINF);
     69       fixbr(dval[j], M3_BFP_ROUND_NEGINF);
     70    }
     71 
     72    return 0;
     73 }
     74