1 #include <stdio.h> 2 #include "opcodes.h" 3 #include "dfp_utils.h" 4 #define __STDC_WANT_DEC_FP__ 1 5 #include <float.h> 6 7 #define I2D(insn, initial, target,round) \ 8 ({ \ 9 register int source asm("2") = initial; \ 10 register typeof(target) _t asm("f0"); \ 11 asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source)); \ 12 _t; \ 13 }) 14 15 #define D2I(insn, initial, type, round, cc) \ 16 ({ \ 17 register type source asm("f0") = initial; \ 18 register int target asm ("2") = 0; \ 19 asm volatile(insn(round,0,2,0) \ 20 "ipm %1\n\t" \ 21 "srl %1,28\n\t" \ 22 :"=d" (target), "=d" (cc) :"f"(source):"cc"); \ 23 target; \ 24 }) 25 26 27 #define DO_PRINT_I2D(insn, l, d, round) \ 28 ({ \ 29 printf(#insn " round=%d %d -> ", 0x##round, l); \ 30 d = I2D(insn, l, d, round); \ 31 DFP_VAL_PRINT(d, typeof(d)); \ 32 printf("\n"); \ 33 }) 34 35 #define DO_INSN_I2D(insn, round, type) \ 36 ({ \ 37 type d; \ 38 DO_PRINT_I2D(insn, 0, d, round); \ 39 DO_PRINT_I2D(insn, 1, d, round); \ 40 DO_PRINT_I2D(insn, 0xffffffff, d, round); \ 41 DO_PRINT_I2D(insn, 0x80000000, d, round); \ 42 DO_PRINT_I2D(insn, 0x7fffffff, d, round); \ 43 }) 44 45 #define DO_PRINT_D2I(insn, d, type, round, cc) \ 46 ({ \ 47 printf(#insn " round=%d ", 0x##round); \ 48 DFP_VAL_PRINT(d, type); \ 49 printf(" -> %d ", D2I(insn, d, type, round, cc)); \ 50 printf("cc=%d\n", cc); \ 51 }) 52 53 #define DO_INSN_D2I(insn, round, type) \ 54 ({ \ 55 int cc; \ 56 type d; \ 57 d = -1.1DD; \ 58 DO_PRINT_D2I(insn, d, type, round, cc); \ 59 d = 0.DD; \ 60 DO_PRINT_D2I(insn, d, type, round, cc); \ 61 d = 1.DD; \ 62 DO_PRINT_D2I(insn, d, type, round, cc); \ 63 d = 1.4DD; \ 64 DO_PRINT_D2I(insn, d, type, round, cc); \ 65 d = 1.5DD; \ 66 DO_PRINT_D2I(insn, d, type, round, cc); \ 67 d = 1.6DD; \ 68 DO_PRINT_D2I(insn, d, type, round, cc); \ 69 d = 1.6E+4DD; \ 70 DO_PRINT_D2I(insn, d, type, round, cc); \ 71 d = 1.6E+8DD; \ 72 DO_PRINT_D2I(insn, d, type, round, cc); \ 73 d = 1.6E+4DD; \ 74 DO_PRINT_D2I(insn, d, type, round, cc); \ 75 d = 1.6E+12DD; \ 76 DO_PRINT_D2I(insn, d, type, round, cc); \ 77 d = 1.6E+20DD; \ 78 DO_PRINT_D2I(insn, d, type, round, cc); \ 79 d = 1.6E+200DD; \ 80 DO_PRINT_D2I(insn, d, type, round, cc); \ 81 d = 1.6E-4DD; \ 82 DO_PRINT_D2I(insn, d, type, round, cc); \ 83 d = DEC32_MIN; \ 84 DO_PRINT_D2I(insn, d, type, round, cc); \ 85 d = DEC32_MAX; \ 86 DO_PRINT_D2I(insn, d, type, round, cc); \ 87 d = DEC64_MIN; \ 88 DO_PRINT_D2I(insn, d, type, round, cc); \ 89 d = DEC64_MAX; \ 90 DO_PRINT_D2I(insn, d, type, round, cc); \ 91 }) 92 93 #define DO_D2I(round) \ 94 ({ \ 95 DO_INSN_D2I(CGDTRA, round, _Decimal64); \ 96 DO_INSN_D2I(CGXTRA, round, _Decimal128); \ 97 }) 98 99 100 int main() 101 { 102 /* rounding mode is not used for the I64 -> D128 conversion */ 103 DO_INSN_I2D(CXGTRA, 0, _Decimal128); 104 105 /* Omit rounding mode value 0 and 2 as the current DFP rounding 106 mode is chosen for these values. */ 107 DO_INSN_I2D(CDGTRA, 1, _Decimal64); 108 DO_D2I(1); 109 110 DO_INSN_I2D(CDGTRA, 3, _Decimal64); 111 DO_D2I(3); 112 113 DO_INSN_I2D(CDGTRA, 4, _Decimal64); 114 DO_D2I(4); 115 116 DO_INSN_I2D(CDGTRA, 5, _Decimal64); 117 DO_D2I(5); 118 119 DO_INSN_I2D(CDGTRA, 6, _Decimal64); 120 DO_D2I(6); 121 122 DO_INSN_I2D(CDGTRA, 7, _Decimal64); 123 DO_D2I(7); 124 125 DO_INSN_I2D(CDGTRA, 8, _Decimal64); 126 DO_D2I(8); 127 128 DO_INSN_I2D(CDGTRA, 9, _Decimal64); 129 DO_D2I(9); 130 131 DO_INSN_I2D(CDGTRA, a, _Decimal64); 132 DO_D2I(a); 133 134 DO_INSN_I2D(CDGTRA, b, _Decimal64); 135 DO_D2I(b); 136 137 DO_INSN_I2D(CDGTRA, c, _Decimal64); 138 DO_D2I(c); 139 140 DO_INSN_I2D(CDGTRA, d, _Decimal64); 141 DO_D2I(d); 142 143 DO_INSN_I2D(CDGTRA, e, _Decimal64); 144 DO_D2I(e); 145 146 DO_INSN_I2D(CDGTRA, f, _Decimal64); 147 DO_D2I(f); 148 149 return 0; 150 } 151