1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdio.h> 2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <assert.h> 3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdint.h> 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <inttypes.h> 5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "opcodes.h" 6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Test "convert from fixed" with universally available rounding modes. 8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Rounding mode is provided via FPC. */ 9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvolatile int32_t i32; 11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvolatile int64_t i64; 12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst char * 14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovrtext(unsigned fpc_round) 15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (fpc_round) { 17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case 0: return "[-> near]"; 18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case 1: return "[-> zero]"; 19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case 2: return "[-> +inf]"; 20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov case 3: return "[-> -inf]"; 21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(0); 23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid 26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovset_rounding_mode(unsigned mode) 27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("setting FPC rounding mode to %s\n", rtext(mode)); 29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov register unsigned r asm("1") = mode; 30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ volatile ( SFPC(1) : : "d"(r) ); 31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid cefbr(unsigned mode) 34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_rounding_mode(mode); 36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov float out; 38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ volatile("cefbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i32)); 40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("cefbr: %"PRId32" -> %f\n", i32, out); 41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid cegbr(unsigned mode) 44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_rounding_mode(mode); 46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov float out; 48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ volatile("cegbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64)); 50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("cegbr: %"PRId64" -> %f\n", i64, out); 51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid cdgbr(unsigned mode) 54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_rounding_mode(mode); 56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov double out; 58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ volatile("cdgbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64)); 60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("cegbr: %"PRId64" -> %f\n", i64, out); 61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint main() 65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int mode; 67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* i32 -> f32 */ 69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov i32 = INT32_MAX; 70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (mode = 0; mode <= 3; ++mode) cefbr(mode); 71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("\n"); 72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov i32 = INT32_MIN; 73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (mode = 0; mode <= 3; ++mode) cefbr(mode); 74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("\n"); 75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* i64 -> f32 */ 77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov i64 = INT64_MAX; 78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (mode = 0; mode <= 3; ++mode) cegbr(mode); 79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("\n"); 80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov i64 = INT64_MIN; 81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (mode = 0; mode <= 3; ++mode) cegbr(mode); 82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("\n"); 83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* i64 -> f64 */ 85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov i64 = INT64_MAX; 86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (mode = 0; mode <= 3; ++mode) cdgbr(mode); 87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("\n"); 88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov i64 = INT64_MIN; 89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (mode = 0; mode <= 3; ++mode) cdgbr(mode); 90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("\n"); 91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 0; 93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 94