#include <stdio.h> #include <stdint.h> #include "dfp_utils.h" #define __STDC_WANT_DEC_FP__ 1 #include <float.h> #ifndef PFPO_FUNCTIONS #define PFPO_FUNCTIONS #define PFPO_F32_TO_D32 0x01080500 #define PFPO_D32_TO_F32 0x01050800 #define PFPO_F32_TO_D64 0x01090500 #define PFPO_D32_TO_F64 0x01060800 #define PFPO_F32_TO_D128 0x010A0500 #define PFPO_D32_TO_F128 0x01070800 #define PFPO_F64_TO_D32 0x01080600 #define PFPO_D64_TO_F32 0x01050900 #define PFPO_F64_TO_D64 0x01090600 #define PFPO_D64_TO_F64 0x01060900 #define PFPO_F64_TO_D128 0x010A0600 #define PFPO_D64_TO_F128 0x01070900 #define PFPO_D128_TO_F64 0x01060A00 #define PFPO_F128_TO_D32 0x01080700 #define PFPO_D128_TO_F32 0x01050A00 #define PFPO_F128_TO_D64 0x01090700 #define PFPO_D128_TO_F64 0x01060A00 #define PFPO_F128_TO_D128 0x010A0700 #define PFPO_D128_TO_F128 0x01070A00 #define PFPO(initial, src_type, dst_type, fn_code, round, ret_code, cc) \ ({ \ register src_type src_reg asm("f4") = initial; \ register dst_type dst_reg asm("f0"); \ register unsigned long fn asm("0") = fn_code | (round & 0xf); \ register unsigned int ret asm("1"); \ asm volatile(".short 0x010a\n\t" \ "ipm %2\n\t" \ "srl %2,28\n\t" \ :"=f"(dst_reg), "=d"(ret), "=d" (cc) \ : "f"(src_reg), "d"(fn)); \ ret_code = ret; \ dst_reg; \ }) #endif /* PFPO_FUNCTIONS */ /* Test BFP <-> DFP conversions */ int main() { int cc; uint8_t i, j; unsigned int ret_code; float f32; double f64; long double f128; _Decimal32 d32; _Decimal64 d64; _Decimal128 d128; float f32_in[] = {123.5656789, FLT_MAX, FLT_MIN}; double f64_in[] = {123456789999.5656789, DBL_MIN, DBL_MAX}; long double f128_in[] = {1234567812345678912345678912.5656789L, LDBL_MIN, LDBL_MAX}; _Decimal32 d32_in[] = {123.5656789DF, DEC32_MAX, DEC32_MIN}; _Decimal64 d64_in[] = {123456789999.5656789DD, DEC64_MIN, DEC64_MAX}; _Decimal128 d128_in[] = {1234567812345678912345678912.5656789DL, DEC128_MIN, DEC128_MAX}; /* valid function code */ PFPO(0., double, _Decimal64, 0x81090600, 0, ret_code, cc); printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81090600, ret_code, cc); /* invalid function code */ PFPO(0., double, _Decimal64, 0x81990600, 0, ret_code, cc); printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81990600, ret_code, cc); for (i = 0; i < 16; i++) { if (i < 2 || i > 7) { /* f32 -> d32 */ for(j = 0; j < 3; j++) { printf("f32 -> d32: round=%x ", i); printf("%f -> ", f32_in[j]); d32 = PFPO(f32_in[j], float, _Decimal32, PFPO_F32_TO_D32, i, ret_code, cc); DFP_VAL_PRINT(d32, _Decimal32); printf(" ret=%d cc=%d\n", ret_code, cc); } /* f32 -> d64 */ for(j = 0; j < 3; j++) { printf("f32 -> d64: round=%x ", i); printf("%f -> ", f32_in[j]); d64 = PFPO(f32_in[j], float, _Decimal64, PFPO_F32_TO_D64, i, ret_code, cc); DFP_VAL_PRINT(d64, _Decimal64); printf(" ret=%d cc=%d\n", ret_code, cc); } /* f32 -> d128 */ for(j = 0; j < 3; j++) { printf("f32 -> d128: round=%x ", i); printf("%f -> ", f32_in[j]); d128 = PFPO(f32_in[j], float, _Decimal128, PFPO_F32_TO_D128, i, ret_code, cc); DFP_VAL_PRINT(d128, _Decimal128); printf(" ret=%d cc=%d\n", ret_code, cc); } /* f64 -> d32 */ for(j = 0; j < 3; j++) { printf("f64 -> d32: round=%x ", i); printf("%lf -> ", f64_in[j]); d32 = PFPO(f64_in[j], double, _Decimal32, PFPO_F64_TO_D32, i, ret_code, cc); DFP_VAL_PRINT(d32, _Decimal32); printf(" ret=%d cc=%d\n", ret_code, cc); } /* f64 -> d64 */ for(j = 0; j < 3; j++) { printf("f64 -> d64: round=%x ", i); printf("%lf -> ", f64_in[j]); d64 = PFPO(f64_in[j], double, _Decimal64, PFPO_F64_TO_D64, i, ret_code, cc); DFP_VAL_PRINT(d64, _Decimal64); printf(" ret=%d cc=%d\n", ret_code, cc); } /* f64 -> d128 */ for(j = 0; j < 3; j++) { printf("f64 -> d128: round=%x ", i); printf("%lf -> ", f64_in[j]); d128 = PFPO(f64_in[j], double, _Decimal128, PFPO_F64_TO_D128, i, ret_code, cc); DFP_VAL_PRINT(d128, _Decimal128); printf(" ret=%d cc=%d\n", ret_code, cc); } /* f128 -> d32 */ for(j = 0; j < 3; j++) { printf("f128 -> d32: round=%x ", i); printf("%Lf -> ", f128_in[j]); d32 = PFPO(f128_in[j], long double, _Decimal32, PFPO_F128_TO_D32, i, ret_code, cc); DFP_VAL_PRINT(d32, _Decimal32); printf(" ret=%d cc=%d\n", ret_code, cc); } /* f128 -> d64 */ for(j = 0; j < 3; j++) { printf("f128 -> d6: round=%x ", i); printf("%Lf -> ", f128_in[j]); d64 = PFPO(f128_in[j], long double, _Decimal64, PFPO_F128_TO_D64, i, ret_code, cc); DFP_VAL_PRINT(d64, _Decimal64); printf(" ret=%d cc=%d\n", ret_code, cc); } /* f128 -> d128 */ for(j = 0; j < 3; j++) { printf("f128 -> d128: round=%x ", i); printf("%Lf -> ", f128_in[j]); d128 = PFPO(f128_in[j], long double, _Decimal128, PFPO_F128_TO_D128, i, ret_code, cc); DFP_VAL_PRINT(d128, _Decimal128); printf(" ret=%d cc=%d\n", ret_code, cc); } /* d32 -> f32 */ for(j = 0; j < 3; j++) { printf("d32 -> f32: round=%x ", i); DFP_VAL_PRINT(d32_in[j], _Decimal32); printf(" -> "); f32 = PFPO(d32_in[j], _Decimal32, float, PFPO_D32_TO_F32, i, ret_code, cc); printf("%f", f32); printf(" ret=%d cc=%d\n", ret_code, cc); } /* d32 -> f64 */ for(j = 0; j < 3; j++) { printf("d32 -> f64: round=%x ", i); DFP_VAL_PRINT(d32_in[j], _Decimal32); printf(" -> "); f64 = PFPO(d32_in[j], _Decimal32, double, PFPO_D32_TO_F64, i, ret_code, cc); printf("%lf", f64); printf(" ret=%d cc=%d\n", ret_code, cc); } /* d32 -> f128 */ for(j = 0; j < 3; j++) { printf("d32 -> f128: round=%x ", i); DFP_VAL_PRINT(d32_in[j], _Decimal32); printf(" -> "); f128 = PFPO(d32_in[j], _Decimal32, long double, PFPO_D32_TO_F128, i, ret_code, cc); printf("%Lf", f128); printf(" ret=%d cc=%d\n", ret_code, cc); } /* d64 -> f32 */ for(j = 0; j < 3; j++) { printf("d64 -> f32: round=%x ", i); DFP_VAL_PRINT(d64_in[j], _Decimal64); printf(" -> "); f32 = PFPO(d64_in[j], _Decimal64, float, PFPO_D64_TO_F32, i, ret_code, cc); printf("%f", f32); printf(" ret=%d cc=%d\n", ret_code, cc); } /* d64 -> f64 */ for(j = 0; j < 3; j++) { printf("d64 -> f64: round=%x ", i); DFP_VAL_PRINT(d64_in[j], _Decimal64); printf(" -> "); f64 = PFPO(d64_in[j], _Decimal64, double, PFPO_D64_TO_F64, i, ret_code, cc); printf("%lf", f64); printf(" ret=%d cc=%d\n", ret_code, cc); } /* d64 -> f128 */ for(j = 0; j < 3; j++) { printf("d64 -> f128: round=%x ", i); DFP_VAL_PRINT(d64_in[j], _Decimal64); printf(" -> "); f128 = PFPO(d64_in[j], _Decimal64, long double, PFPO_D64_TO_F128, i, ret_code, cc); printf("%Lf", f128); printf(" ret=%d cc=%d\n", ret_code, cc); } /* d128 -> f32 */ for(j = 0; j < 3; j++) { printf("d128 -> f32: round=%x ", i); DFP_VAL_PRINT(d128_in[j], _Decimal128); printf(" -> "); f32 = PFPO(d128_in[j], _Decimal128, float, PFPO_D128_TO_F32, i, ret_code, cc); printf("%f", f32); printf(" ret=%d cc=%d\n", ret_code, cc); } /* d128 -> f64 */ for(j = 0; j < 3; j++) { printf("d128 -> f64: round=%x ", i); DFP_VAL_PRINT(d128_in[j], _Decimal128); printf(" -> "); f64 = PFPO(d128_in[j], _Decimal128, double, PFPO_D128_TO_F64, i, ret_code, cc); printf("%lf", f64); printf(" ret=%d cc=%d\n", ret_code, cc); } /* d128 -> f128 */ for(j = 0; j < 3; j++) { printf("d128 -> f128: round=%x ", i); DFP_VAL_PRINT(d128_in[j], _Decimal128); printf(" -> "); f128 = PFPO(d128_in[j], _Decimal128, long double, PFPO_D128_TO_F128, i, ret_code, cc); printf("%Lf", f128); printf(" ret=%d cc=%d\n", ret_code, cc); } } } return 0; }