Home | History | Annotate | Download | only in s390x
      1 #include <stdio.h>
      2 #include <assert.h>
      3 #include <stdint.h>
      4 #include <inttypes.h>
      5 #include "opcodes.h"
      6 
      7 /* Test "convert from fixed" with universally available rounding modes.
      8    Rounding mode is provided via FPC. */
      9 
     10 volatile int32_t i32;
     11 volatile int64_t i64;
     12 
     13 const char *
     14 rtext(unsigned fpc_round)
     15 {
     16    switch (fpc_round) {
     17    case 0: return "[-> near]";
     18    case 1: return "[-> zero]";
     19    case 2: return "[-> +inf]";
     20    case 3: return "[-> -inf]";
     21    }
     22    assert(0);
     23 }
     24 
     25 void
     26 set_rounding_mode(unsigned mode)
     27 {
     28    printf("setting FPC rounding mode to %s\n", rtext(mode));
     29    register unsigned r asm("1") = mode;
     30    __asm__ volatile ( SFPC(1) : : "d"(r) );
     31 }
     32 
     33 void cefbr(unsigned mode)
     34 {
     35    set_rounding_mode(mode);
     36 
     37    float out;
     38 
     39    __asm__ volatile("cefbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i32));
     40    printf("cefbr:  %"PRId32" -> %f\n", i32, out);
     41 }
     42 
     43 void cegbr(unsigned mode)
     44 {
     45    set_rounding_mode(mode);
     46 
     47    float out;
     48 
     49    __asm__ volatile("cegbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
     50    printf("cegbr:  %"PRId64" -> %f\n", i64, out);
     51 }
     52 
     53 void cdgbr(unsigned mode)
     54 {
     55    set_rounding_mode(mode);
     56 
     57    double out;
     58 
     59    __asm__ volatile("cdgbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
     60    printf("cegbr:  %"PRId64" -> %f\n", i64, out);
     61 }
     62 
     63 
     64 int main()
     65 {
     66    int mode;
     67 
     68    /* i32 -> f32 */
     69    i32 = INT32_MAX;
     70    for (mode = 0; mode <= 3; ++mode) cefbr(mode);
     71    printf("\n");
     72    i32 = INT32_MIN;
     73    for (mode = 0; mode <= 3; ++mode) cefbr(mode);
     74    printf("\n");
     75 
     76    /* i64 -> f32 */
     77    i64 = INT64_MAX;
     78    for (mode = 0; mode <= 3; ++mode) cegbr(mode);
     79    printf("\n");
     80    i64 = INT64_MIN;
     81    for (mode = 0; mode <= 3; ++mode) cegbr(mode);
     82    printf("\n");
     83 
     84    /* i64 -> f64 */
     85    i64 = INT64_MAX;
     86    for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
     87    printf("\n");
     88    i64 = INT64_MIN;
     89    for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
     90    printf("\n");
     91 
     92    return 0;
     93 }
     94