#include <stdio.h> #include <assert.h> #include <stdint.h> #include <inttypes.h> #include "opcodes.h" /* Test "convert from fixed" with universally available rounding modes. Rounding mode is provided via FPC. */ volatile int32_t i32; volatile int64_t i64; const char * rtext(unsigned fpc_round) { switch (fpc_round) { case 0: return "[-> near]"; case 1: return "[-> zero]"; case 2: return "[-> +inf]"; case 3: return "[-> -inf]"; } assert(0); } void set_rounding_mode(unsigned mode) { printf("setting FPC rounding mode to %s\n", rtext(mode)); register unsigned r asm("1") = mode; __asm__ volatile ( SFPC(1) : : "d"(r) ); } void cefbr(unsigned mode) { set_rounding_mode(mode); float out; __asm__ volatile("cefbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i32)); printf("cefbr: %"PRId32" -> %f\n", i32, out); } void cegbr(unsigned mode) { set_rounding_mode(mode); float out; __asm__ volatile("cegbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64)); printf("cegbr: %"PRId64" -> %f\n", i64, out); } void cdgbr(unsigned mode) { set_rounding_mode(mode); double out; __asm__ volatile("cdgbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64)); printf("cegbr: %"PRId64" -> %f\n", i64, out); } int main() { int mode; /* i32 -> f32 */ i32 = INT32_MAX; for (mode = 0; mode <= 3; ++mode) cefbr(mode); printf("\n"); i32 = INT32_MIN; for (mode = 0; mode <= 3; ++mode) cefbr(mode); printf("\n"); /* i64 -> f32 */ i64 = INT64_MAX; for (mode = 0; mode <= 3; ++mode) cegbr(mode); printf("\n"); i64 = INT64_MIN; for (mode = 0; mode <= 3; ++mode) cegbr(mode); printf("\n"); /* i64 -> f64 */ i64 = INT64_MAX; for (mode = 0; mode <= 3; ++mode) cdgbr(mode); printf("\n"); i64 = INT64_MIN; for (mode = 0; mode <= 3; ++mode) cdgbr(mode); printf("\n"); return 0; }