1#include <stdio.h> 2#include <stdint.h> 3#include "dfp_utils.h" 4 5/* Test various DFP ops: 6 - extract biased exponent 64/128 bit 7 - extract significance 64/128 bit 8 - insert biased exponent 64/128 bit 9 - load and test 64/128 bit 10 - shift left/right 64/128 bit 11 - reround 64/128 bit 12*/ 13 14void eedtr(_Decimal64 in) 15{ 16 long out; 17 asm volatile(".insn rre, 0xb3e50000, %[out], %[in]\n\t" 18 :[out] "=d" (out) :[in] "f" (in)); 19 printf("EEDTR "); 20 DFP_VAL_PRINT(in, _Decimal64); 21 printf(" -> %ld\n", out); 22} 23 24void eextr(_Decimal128 in) 25{ 26 long out; 27 asm volatile(".insn rre, 0xb3ed0000, %[out], %[in]\n\t" 28 :[out] "=d" (out) :[in] "f" (in)); 29 printf("EEXTR "); 30 DFP_VAL_PRINT(in, _Decimal128); 31 printf(" -> %ld\n", out); 32} 33 34void esdtr(_Decimal64 in) 35{ 36 long out; 37 asm volatile(".insn rre, 0xb3e70000, %[out], %[in]\n\t" 38 :[out] "=d" (out) :[in] "f" (in)); 39 printf("ESDTR "); 40 DFP_VAL_PRINT(in, _Decimal64); 41 printf(" -> %ld\n", out); 42} 43 44void esxtr(_Decimal128 in) 45{ 46 long out; 47 asm volatile(".insn rre, 0xb3ef0000, %[out], %[in]\n\t" 48 :[out] "=d" (out) :[in] "f" (in)); 49 printf("ESXTR "); 50 DFP_VAL_PRINT(in, _Decimal128); 51 printf(" -> %ld\n", out); 52} 53 54void iedtr(_Decimal64 in, long amount) 55{ 56 _Decimal64 out; 57 58 asm volatile (".insn rrf, 0xb3f60000, %[out], %[amount], %[in], 0\n\t" 59 :[out]"=f"(out) 60 :[in]"f"(in), [amount]"d"(amount)); 61 62 printf("IEDTR "); 63 DFP_VAL_PRINT(in, _Decimal64); 64 printf(", %ld -> ", amount); 65 DFP_VAL_PRINT(out, _Decimal64); 66 printf("\n"); 67} 68 69void iextr(_Decimal128 in, long amount) 70{ 71 _Decimal128 out; 72 73 asm volatile (".insn rrf, 0xb3fe0000, %[out], %[amount], %[in], 0\n\t" 74 :[out]"=f"(out) 75 :[in]"f"(in), [amount]"d"(amount)); 76 77 printf("IEXTR "); 78 DFP_VAL_PRINT(in, _Decimal128); 79 printf(", %ld -> ", amount); 80 DFP_VAL_PRINT(out, _Decimal128); 81 printf("\n"); 82} 83 84void ltdtr(_Decimal64 in) 85{ 86 _Decimal64 out; 87 int cc; 88 asm volatile(".insn rre, 0xb3d60000, %[out], %[in]\n\t" 89 "ipm %1\n\t" 90 "srl %1,28\n\t" 91 :[out] "=d" (out), "=d" (cc) 92 :[in] "f" (in)); 93 printf("LTDTR "); 94 DFP_VAL_PRINT(in, _Decimal64); 95 printf(" -> %d\n", cc); 96} 97 98void ltxtr(_Decimal128 in) 99{ 100 _Decimal128 out; 101 int cc; 102 asm volatile(".insn rre, 0xb3de0000, %[out], %[in]\n\t" 103 "ipm %1\n\t" 104 "srl %1,28\n\t" 105 :[out] "=f" (out), "=d" (cc) 106 :[in] "f" (in)); 107 printf("LTXTR "); 108 DFP_VAL_PRINT(in, _Decimal128); 109 printf(" -> %d\n", cc); 110} 111 112void qadtr(_Decimal64 op, _Decimal64 quan, uint8_t rm) 113{ 114 _Decimal64 out; 115 116 asm volatile ( 117 ".insn rrf, 0xb3f50000, %[out], %[quan], %[op], %[rm]\n\t" 118 :[out]"=f"(out) 119 :[op]"f"(op), [quan]"f"(quan), [rm]"d"(rm) 120 ); 121 printf("QADTR "); 122 DFP_VAL_PRINT(op, _Decimal64); 123 printf(", "); 124 DFP_VAL_PRINT(quan, _Decimal64); 125 printf(", %x -> ", rm); 126 DFP_VAL_PRINT(out, _Decimal64); 127 printf("\n"); 128} 129 130void quantize64(_Decimal64 op, _Decimal64 quan) 131{ 132 uint8_t i; 133 134 for (i = 0; i < 16; i++) 135 qadtr(op, quan, i); 136} 137 138void qaxtr(_Decimal128 op, _Decimal128 quan, uint8_t rm) 139{ 140 _Decimal128 out; 141 142 asm volatile ( 143 ".insn rrf, 0xb3fd0000, %[out], %[quan], %[op], %[rm]\n\t" 144 :[out]"=f"(out) 145 :[op]"f"(op), [quan]"f"(quan), [rm]"d"(rm) 146 ); 147 printf("QAXTR "); 148 DFP_VAL_PRINT(op, _Decimal128); 149 printf(", "); 150 DFP_VAL_PRINT(quan, _Decimal128); 151 printf(", %x -> ", rm); 152 DFP_VAL_PRINT(out, _Decimal128); 153 printf("\n"); 154} 155 156void quantize128(_Decimal128 op, _Decimal128 quan) 157{ 158 uint8_t i; 159 160 for (i = 0; i < 16; i++) 161 qaxtr(op, quan, i); 162} 163 164void rrdtr(_Decimal64 op, uint8_t sig, uint8_t rm) 165{ 166 _Decimal64 out; 167 168 asm volatile ( 169 ".insn rrf, 0xb3f70000, %[out], %[sig], %[op], %[rm]\n\t" 170 :[out]"=f"(out) 171 :[op]"f"(op), [sig]"d"(sig), [rm]"d"(rm) 172 ); 173 printf("RRDTR "); 174 DFP_VAL_PRINT(op, _Decimal64); 175 printf(", %d, %x -> ", sig, rm); 176 DFP_VAL_PRINT(out, _Decimal64); 177 printf("\n"); 178} 179 180void reround64(_Decimal64 op, uint8_t sig) 181{ 182 uint8_t i; 183 184 for (i = 0; i < 16; i++) 185 rrdtr(op, sig, i); 186} 187 188void rrxtr(_Decimal128 op, uint8_t sig, uint8_t rm) 189{ 190 _Decimal128 out; 191 192 asm volatile ( 193 ".insn rrf, 0xb3ff0000, %[out], %[sig], %[op], %[rm]\n\t" 194 :[out]"=f"(out) 195 :[op]"f"(op), [sig]"d"(sig), [rm]"d"(rm) 196 ); 197 printf("RRXTR "); 198 DFP_VAL_PRINT(op, _Decimal128); 199 printf(", %d, %x -> ", sig, rm); 200 DFP_VAL_PRINT(out, _Decimal128); 201 printf("\n"); 202} 203 204void reround128(_Decimal128 op, uint8_t sig) 205{ 206 uint8_t i; 207 208 for (i = 0; i < 16; i++) 209 rrxtr(op, sig, i); 210} 211 212void sldt(_Decimal64 in, unsigned long amount) 213{ 214 _Decimal64 out; 215 int *shift = (int *) amount; 216 217 asm volatile (".insn rxf, 0xed0000000040, %[out], %[in], 0(%[amount])\n\t" 218 :[out]"=f"(out) 219 :[in]"f"(in),[amount]"a"(shift)); 220 221 printf("SLDT "); 222 DFP_VAL_PRINT(in, _Decimal64); 223 printf(" -> "); 224 DFP_VAL_PRINT(out, _Decimal64); 225 printf("\n"); 226} 227 228void slxt(_Decimal128 in, unsigned long amount) 229{ 230 _Decimal128 out; 231 int *shift = (int *) amount; 232 233 asm volatile (".insn rxf, 0xed0000000048, %[out], %[in], 0(%[amount])\n\t" 234 :[out]"=f"(out) 235 :[in]"f"(in),[amount]"a"(shift)); 236 237 printf("SLXT "); 238 DFP_VAL_PRINT(in, _Decimal128); 239 printf(" -> "); 240 DFP_VAL_PRINT(out, _Decimal128); 241 printf("\n"); 242} 243 244void srdt(_Decimal64 in, unsigned long amount) 245{ 246 _Decimal64 out; 247 int *shift = (int *) amount; 248 249 asm volatile (".insn rxf, 0xed0000000041, %[out], %[in], 0(%[amount])\n\t" 250 :[out]"=f"(out) 251 :[in]"f"(in),[amount]"a"(shift)); 252 253 printf("SRDT "); 254 DFP_VAL_PRINT(in, _Decimal64); 255 printf(" -> "); 256 DFP_VAL_PRINT(out, _Decimal64); 257 printf("\n"); 258} 259 260void srxt(_Decimal128 in, unsigned long amount) 261{ 262 _Decimal128 out; 263 int *shift = (int *) amount; 264 265 asm volatile (".insn rxf, 0xed0000000049, %[out], %[in], 0(%[amount])\n\t" 266 :[out]"=f"(out) 267 :[in]"f"(in),[amount]"a"(shift)); 268 269 printf("SRXT "); 270 DFP_VAL_PRINT(in, _Decimal128); 271 printf(" -> "); 272 DFP_VAL_PRINT(out, _Decimal128); 273 printf("\n"); 274} 275 276int main() { 277 _Decimal64 d64 = 50.0005DD; 278 _Decimal128 d128 = 50.0005DL; 279 280 eedtr(d64); 281 eedtr(-d64); 282 eedtr(0.DD); 283 eextr(d128); 284 eextr(-d128); 285 eextr(0.DL); 286 287 esdtr(d64); 288 esdtr(-d64); 289 esdtr(0.DD); 290 esxtr(d128); 291 esxtr(-d128); 292 esxtr(0.DL); 293 294 ltdtr(d64); 295 ltdtr(-d64); 296 ltdtr(0.0DD); 297 ltxtr(d128); 298 ltxtr(-d128); 299 ltxtr(0.0DL); 300 301 d64 = 12345678.54321DD; 302 sldt(d64, 10); 303 sldt(-d64, 2); 304 sldt(0.DD, 2); 305 sldt(-0.DD, 2); 306 307 srdt(d64, 5); 308 srdt(-d64, 2); 309 srdt(0.DD, 2); 310 srdt(-0.DD, 2); 311 312 d128 = 12345678.54321DL; 313 slxt(d128, 10); 314 slxt(-d128, 2); 315 slxt(0.DL, 2); 316 slxt(-0.DL, 2); 317 318 srxt(d128, 10); 319 srxt(-d128, 2); 320 srxt(0.DL, 2); 321 srxt(-0.DL, 2); 322 323 d64 = 5.000005DD; 324 iedtr(d64, 391); 325 iedtr(d64, 392); 326 iedtr(d64, 393); 327 iedtr(-d64, 391); 328 iedtr(-d64, 392); 329 iedtr(-d64, 393); 330 iedtr(0.DD, 393); 331 iedtr(-0.DD, 393); 332 iedtr(1.DD, 393); 333 334 d128 = 5.000005DL; 335 iextr(d128, 6169); 336 iextr(d128, 6170); 337 iextr(d128, 6171); 338 iextr(-d128, 6169); 339 iextr(-d128, 6170); 340 iextr(-d128, 6171); 341 iextr(0.DL, 6171); 342 iextr(-0.DL, 6171); 343 iextr(1.DL, 6171); 344 345 d64 = 2.171234DD; 346 quantize64(d64, 0.001DD); 347 quantize64(-d64, 0.001DD); 348 quantize64(-d64, 0.DD); 349 quantize64(0.DD, 0.001DD); 350 351 d128 = 26365343648.171234DL; 352 quantize128(d128, 230.01DL); 353 quantize128(-d128, 230.01DL); 354 quantize128(d128, 0.DL); 355 quantize128(-0.DL, 230.01DL); 356 357 d64 = 2.174598DD; 358 reround64(d64, 3); 359 reround64(d64, 4); 360 reround64(d64, 5); 361 reround64(-d64, 3); 362 reround64(-d64, 4); 363 reround64(-d64, 5); 364 reround64(0.DD, 0); 365 366 d128 = 2.174598DL; 367 reround128(d128, 3); 368 reround128(d128, 4); 369 reround128(d128, 5); 370 reround128(-d128, 3); 371 reround128(-d128, 4); 372 reround128(-d128, 5); 373 reround128(0.DL, 0); 374 375 return 0; 376} 377