| #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; |
| } |