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 10volatile int32_t i32; 11volatile int64_t i64; 12 13const char * 14rtext(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 25void 26set_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 33void 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 43void 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 53void 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 64int 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