1 #include <stdio.h> 2 #include <stdint.h> 3 #include "dfp_utils.h" 4 #define __STDC_WANT_DEC_FP__ 1 5 #include <float.h> 6 7 #ifndef PFPO_FUNCTIONS 8 #define PFPO_FUNCTIONS 9 #define PFPO_F32_TO_D32 0x01080500 10 #define PFPO_D32_TO_F32 0x01050800 11 #define PFPO_F32_TO_D64 0x01090500 12 #define PFPO_D32_TO_F64 0x01060800 13 #define PFPO_F32_TO_D128 0x010A0500 14 #define PFPO_D32_TO_F128 0x01070800 15 #define PFPO_F64_TO_D32 0x01080600 16 #define PFPO_D64_TO_F32 0x01050900 17 #define PFPO_F64_TO_D64 0x01090600 18 #define PFPO_D64_TO_F64 0x01060900 19 #define PFPO_F64_TO_D128 0x010A0600 20 #define PFPO_D64_TO_F128 0x01070900 21 #define PFPO_D128_TO_F64 0x01060A00 22 #define PFPO_F128_TO_D32 0x01080700 23 #define PFPO_D128_TO_F32 0x01050A00 24 #define PFPO_F128_TO_D64 0x01090700 25 #define PFPO_D128_TO_F64 0x01060A00 26 #define PFPO_F128_TO_D128 0x010A0700 27 #define PFPO_D128_TO_F128 0x01070A00 28 29 #define PFPO(initial, src_type, dst_type, fn_code, round, ret_code, cc) \ 30 ({ \ 31 register src_type src_reg asm("f4") = initial; \ 32 register dst_type dst_reg asm("f0"); \ 33 register unsigned long fn asm("0") = fn_code | (round & 0xf); \ 34 register unsigned int ret asm("1"); \ 35 asm volatile(".short 0x010a\n\t" \ 36 "ipm %2\n\t" \ 37 "srl %2,28\n\t" \ 38 :"=f"(dst_reg), "=d"(ret), "=d" (cc) \ 39 : "f"(src_reg), "d"(fn)); \ 40 ret_code = ret; \ 41 dst_reg; \ 42 }) 43 44 #endif /* PFPO_FUNCTIONS */ 45 46 /* Test BFP <-> DFP conversions */ 47 int main() 48 { 49 int cc; 50 uint8_t i, j; 51 unsigned int ret_code; 52 53 float f32; 54 double f64; 55 long double f128; 56 57 _Decimal32 d32; 58 _Decimal64 d64; 59 _Decimal128 d128; 60 61 float f32_in[] = {123.5656789, FLT_MAX, FLT_MIN}; 62 double f64_in[] = {123456789999.5656789, DBL_MIN, DBL_MAX}; 63 long double f128_in[] = {1234567812345678912345678912.5656789L, 64 LDBL_MIN, LDBL_MAX}; 65 66 _Decimal32 d32_in[] = {123.5656789DF, DEC32_MAX, DEC32_MIN}; 67 _Decimal64 d64_in[] = {123456789999.5656789DD, DEC64_MIN, DEC64_MAX}; 68 _Decimal128 d128_in[] = {1234567812345678912345678912.5656789DL, 69 DEC128_MIN, DEC128_MAX}; 70 71 /* valid function code */ 72 PFPO(0., double, _Decimal64, 0x81090600, 0, ret_code, cc); 73 printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81090600, ret_code, cc); 74 75 /* invalid function code */ 76 PFPO(0., double, _Decimal64, 0x81990600, 0, ret_code, cc); 77 printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81990600, ret_code, cc); 78 79 for (i = 0; i < 16; i++) { 80 if (i < 2 || i > 7) { 81 82 /* f32 -> d32 */ 83 for(j = 0; j < 3; j++) { 84 printf("f32 -> d32: round=%x ", i); 85 printf("%f -> ", f32_in[j]); 86 d32 = PFPO(f32_in[j], float, _Decimal32, PFPO_F32_TO_D32, 87 i, ret_code, cc); 88 DFP_VAL_PRINT(d32, _Decimal32); 89 printf(" ret=%d cc=%d\n", ret_code, cc); 90 } 91 92 /* f32 -> d64 */ 93 for(j = 0; j < 3; j++) { 94 printf("f32 -> d64: round=%x ", i); 95 printf("%f -> ", f32_in[j]); 96 d64 = PFPO(f32_in[j], float, _Decimal64, PFPO_F32_TO_D64, 97 i, ret_code, cc); 98 DFP_VAL_PRINT(d64, _Decimal64); 99 printf(" ret=%d cc=%d\n", ret_code, cc); 100 } 101 102 /* f32 -> d128 */ 103 for(j = 0; j < 3; j++) { 104 printf("f32 -> d128: round=%x ", i); 105 printf("%f -> ", f32_in[j]); 106 d128 = PFPO(f32_in[j], float, _Decimal128, PFPO_F32_TO_D128, 107 i, ret_code, cc); 108 DFP_VAL_PRINT(d128, _Decimal128); 109 printf(" ret=%d cc=%d\n", ret_code, cc); 110 } 111 112 /* f64 -> d32 */ 113 for(j = 0; j < 3; j++) { 114 printf("f64 -> d32: round=%x ", i); 115 printf("%lf -> ", f64_in[j]); 116 d32 = PFPO(f64_in[j], double, _Decimal32, PFPO_F64_TO_D32, 117 i, ret_code, cc); 118 DFP_VAL_PRINT(d32, _Decimal32); 119 printf(" ret=%d cc=%d\n", ret_code, cc); 120 } 121 122 /* f64 -> d64 */ 123 for(j = 0; j < 3; j++) { 124 printf("f64 -> d64: round=%x ", i); 125 printf("%lf -> ", f64_in[j]); 126 d64 = PFPO(f64_in[j], double, _Decimal64, PFPO_F64_TO_D64, 127 i, ret_code, cc); 128 DFP_VAL_PRINT(d64, _Decimal64); 129 printf(" ret=%d cc=%d\n", ret_code, cc); 130 } 131 132 /* f64 -> d128 */ 133 for(j = 0; j < 3; j++) { 134 printf("f64 -> d128: round=%x ", i); 135 printf("%lf -> ", f64_in[j]); 136 d128 = PFPO(f64_in[j], double, _Decimal128, PFPO_F64_TO_D128, 137 i, ret_code, cc); 138 DFP_VAL_PRINT(d128, _Decimal128); 139 printf(" ret=%d cc=%d\n", ret_code, cc); 140 } 141 142 /* f128 -> d32 */ 143 for(j = 0; j < 3; j++) { 144 printf("f128 -> d32: round=%x ", i); 145 printf("%Lf -> ", f128_in[j]); 146 d32 = PFPO(f128_in[j], long double, _Decimal32, PFPO_F128_TO_D32, 147 i, ret_code, cc); 148 DFP_VAL_PRINT(d32, _Decimal32); 149 printf(" ret=%d cc=%d\n", ret_code, cc); 150 } 151 152 /* f128 -> d64 */ 153 for(j = 0; j < 3; j++) { 154 printf("f128 -> d6: round=%x ", i); 155 printf("%Lf -> ", f128_in[j]); 156 d64 = PFPO(f128_in[j], long double, _Decimal64, PFPO_F128_TO_D64, 157 i, ret_code, cc); 158 DFP_VAL_PRINT(d64, _Decimal64); 159 printf(" ret=%d cc=%d\n", ret_code, cc); 160 } 161 162 /* f128 -> d128 */ 163 for(j = 0; j < 3; j++) { 164 printf("f128 -> d128: round=%x ", i); 165 printf("%Lf -> ", f128_in[j]); 166 d128 = PFPO(f128_in[j], long double, _Decimal128, PFPO_F128_TO_D128, 167 i, ret_code, cc); 168 DFP_VAL_PRINT(d128, _Decimal128); 169 printf(" ret=%d cc=%d\n", ret_code, cc); 170 } 171 172 /* d32 -> f32 */ 173 for(j = 0; j < 3; j++) { 174 printf("d32 -> f32: round=%x ", i); 175 DFP_VAL_PRINT(d32_in[j], _Decimal32); 176 printf(" -> "); 177 f32 = PFPO(d32_in[j], _Decimal32, float, PFPO_D32_TO_F32, 178 i, ret_code, cc); 179 printf("%f", f32); 180 printf(" ret=%d cc=%d\n", ret_code, cc); 181 } 182 183 /* d32 -> f64 */ 184 for(j = 0; j < 3; j++) { 185 printf("d32 -> f64: round=%x ", i); 186 DFP_VAL_PRINT(d32_in[j], _Decimal32); 187 printf(" -> "); 188 f64 = PFPO(d32_in[j], _Decimal32, double, PFPO_D32_TO_F64, 189 i, ret_code, cc); 190 printf("%lf", f64); 191 printf(" ret=%d cc=%d\n", ret_code, cc); 192 } 193 194 /* d32 -> f128 */ 195 for(j = 0; j < 3; j++) { 196 printf("d32 -> f128: round=%x ", i); 197 DFP_VAL_PRINT(d32_in[j], _Decimal32); 198 printf(" -> "); 199 f128 = PFPO(d32_in[j], _Decimal32, long double, PFPO_D32_TO_F128, 200 i, ret_code, cc); 201 printf("%Lf", f128); 202 printf(" ret=%d cc=%d\n", ret_code, cc); 203 } 204 205 /* d64 -> f32 */ 206 for(j = 0; j < 3; j++) { 207 printf("d64 -> f32: round=%x ", i); 208 DFP_VAL_PRINT(d64_in[j], _Decimal64); 209 printf(" -> "); 210 f32 = PFPO(d64_in[j], _Decimal64, float, PFPO_D64_TO_F32, 211 i, ret_code, cc); 212 printf("%f", f32); 213 printf(" ret=%d cc=%d\n", ret_code, cc); 214 } 215 216 /* d64 -> f64 */ 217 for(j = 0; j < 3; j++) { 218 printf("d64 -> f64: round=%x ", i); 219 DFP_VAL_PRINT(d64_in[j], _Decimal64); 220 printf(" -> "); 221 f64 = PFPO(d64_in[j], _Decimal64, double, PFPO_D64_TO_F64, 222 i, ret_code, cc); 223 printf("%lf", f64); 224 printf(" ret=%d cc=%d\n", ret_code, cc); 225 } 226 227 /* d64 -> f128 */ 228 for(j = 0; j < 3; j++) { 229 printf("d64 -> f128: round=%x ", i); 230 DFP_VAL_PRINT(d64_in[j], _Decimal64); 231 printf(" -> "); 232 f128 = PFPO(d64_in[j], _Decimal64, long double, PFPO_D64_TO_F128, 233 i, ret_code, cc); 234 printf("%Lf", f128); 235 printf(" ret=%d cc=%d\n", ret_code, cc); 236 } 237 238 /* d128 -> f32 */ 239 for(j = 0; j < 3; j++) { 240 printf("d128 -> f32: round=%x ", i); 241 DFP_VAL_PRINT(d128_in[j], _Decimal128); 242 printf(" -> "); 243 f32 = PFPO(d128_in[j], _Decimal128, float, PFPO_D128_TO_F32, 244 i, ret_code, cc); 245 printf("%f", f32); 246 printf(" ret=%d cc=%d\n", ret_code, cc); 247 } 248 249 /* d128 -> f64 */ 250 for(j = 0; j < 3; j++) { 251 printf("d128 -> f64: round=%x ", i); 252 DFP_VAL_PRINT(d128_in[j], _Decimal128); 253 printf(" -> "); 254 f64 = PFPO(d128_in[j], _Decimal128, double, PFPO_D128_TO_F64, 255 i, ret_code, cc); 256 printf("%lf", f64); 257 printf(" ret=%d cc=%d\n", ret_code, cc); 258 } 259 260 /* d128 -> f128 */ 261 for(j = 0; j < 3; j++) { 262 printf("d128 -> f128: round=%x ", i); 263 DFP_VAL_PRINT(d128_in[j], _Decimal128); 264 printf(" -> "); 265 f128 = PFPO(d128_in[j], _Decimal128, long double, PFPO_D128_TO_F128, 266 i, ret_code, cc); 267 printf("%Lf", f128); 268 printf(" ret=%d cc=%d\n", ret_code, cc); 269 } 270 } 271 } 272 return 0; 273 } 274