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 L2D(insn, initial, target,round) \ 8 ({ \ 9 register unsigned long 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 I2D(insn, initial, target,round) \ 16 ({ \ 17 register int source asm("2") = initial; \ 18 register typeof(target) _t asm("f0"); \ 19 asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source)); \ 20 _t; \ 21}) 22 23#define D2L(insn, initial, type, round, cc) \ 24 ({ \ 25 register type source asm("f0") = initial; \ 26 register unsigned long target asm ("2") = 0; \ 27 asm volatile(insn(round,0,2,0) \ 28 "ipm %1\n\t" \ 29 "srl %1,28\n\t" \ 30 :"=d" (target), "=d" (cc) :"f"(source):"cc"); \ 31 target; \ 32 }) 33 34#define D2I(insn, initial, type, round, cc) \ 35 ({ \ 36 register type source asm("f0") = initial; \ 37 register int target asm ("2") = 0; \ 38 asm volatile(insn(round,0,2,0) \ 39 "ipm %1\n\t" \ 40 "srl %1,28\n\t" \ 41 :"=d" (target), "=d" (cc) :"f"(source):"cc"); \ 42 target; \ 43}) 44 45 46#define DO_PRINT_L2D(insn, l, d, round) \ 47 ({ \ 48 printf(#insn " round=%d %lu -> ", 0x##round, l); \ 49 d = L2D(insn, l, d, round); \ 50 DFP_VAL_PRINT(d, typeof(d)); \ 51 printf("\n"); \ 52 }) 53 54#define DO_INSN_L2D(insn, round, type) \ 55 ({ \ 56 type d; \ 57 DO_PRINT_L2D(insn, 0UL, d, round); \ 58 DO_PRINT_L2D(insn, 1UL, d, round); \ 59 DO_PRINT_L2D(insn, 0xffffffffUL, d, round); \ 60 DO_PRINT_L2D(insn, 0x80000000UL, d, round); \ 61 DO_PRINT_L2D(insn, 0x7fffffffUL, d, round); \ 62 DO_PRINT_L2D(insn, 0x100000000UL, d, round); \ 63 DO_PRINT_L2D(insn, 0xffffffffffffffffUL, d, round); \ 64 DO_PRINT_L2D(insn, 0x8000000000000000UL, d, round); \ 65 DO_PRINT_L2D(insn, 0x7fffffffffffffffUL, d, round); \ 66 }) 67 68#define DO_PRINT_I2D(insn, l, d, round) \ 69 ({ \ 70 printf(#insn " round=%d %d -> ", 0x##round, l); \ 71 d = I2D(insn, l, d, round); \ 72 DFP_VAL_PRINT(d, typeof(d)); \ 73 printf("\n"); \ 74 }) 75 76#define DO_INSN_I2D(insn, round, type) \ 77 ({ \ 78 type d; \ 79 DO_PRINT_I2D(insn, 0, d, round); \ 80 DO_PRINT_I2D(insn, 1, d, round); \ 81 DO_PRINT_I2D(insn, 0xffffffff, d, round); \ 82 DO_PRINT_I2D(insn, 0x80000000, d, round); \ 83 DO_PRINT_I2D(insn, 0x7fffffff, d, round); \ 84 }) 85 86#define DO_PRINT_D2L(insn, d, type, round, cc) \ 87 ({ \ 88 printf(#insn " round=%d ", 0x##round); \ 89 DFP_VAL_PRINT(d, type); \ 90 printf(" -> %lu ", D2L(insn, d, type, round, cc)); \ 91 printf("cc=%d\n", cc); \ 92 }) 93 94#define DO_INSN_D2L(insn, round, type) \ 95 ({ \ 96 int cc; \ 97 type d; \ 98 d = -1.1DD; \ 99 DO_PRINT_D2L(insn, d, type, round, cc); \ 100 d = 0.DD; \ 101 DO_PRINT_D2L(insn, d, type, round, cc); \ 102 d = 1.DD; \ 103 DO_PRINT_D2L(insn, d, type, round, cc); \ 104 d = 1.4DD; \ 105 DO_PRINT_D2L(insn, d, type, round, cc); \ 106 d = 1.5DD; \ 107 DO_PRINT_D2L(insn, d, type, round, cc); \ 108 d = 1.6DD; \ 109 DO_PRINT_D2L(insn, d, type, round, cc); \ 110 d = 1.6E+4DD; \ 111 DO_PRINT_D2L(insn, d, type, round, cc); \ 112 d = 1.6E+8DD; \ 113 DO_PRINT_D2L(insn, d, type, round, cc); \ 114 d = 1.6E+4DD; \ 115 DO_PRINT_D2L(insn, d, type, round, cc); \ 116 d = 1.6E+12DD; \ 117 DO_PRINT_D2L(insn, d, type, round, cc); \ 118 d = 1.6E+20DD; \ 119 DO_PRINT_D2L(insn, d, type, round, cc); \ 120 d = 1.6E+200DD; \ 121 DO_PRINT_D2L(insn, d, type, round, cc); \ 122 d = 1.6E-4DD; \ 123 DO_PRINT_D2L(insn, d, type, round, cc); \ 124 d = DEC32_MIN; \ 125 DO_PRINT_D2L(insn, d, type, round, cc); \ 126 d = DEC32_MAX; \ 127 DO_PRINT_D2L(insn, d, type, round, cc); \ 128 d = DEC64_MIN; \ 129 DO_PRINT_D2L(insn, d, type, round, cc); \ 130 d = DEC64_MAX; \ 131 DO_PRINT_D2L(insn, d, type, round, cc); \ 132 }) 133 134#define DO_PRINT_D2I(insn, d, type, round, cc) \ 135 ({ \ 136 printf(#insn " round=%d ", 0x##round); \ 137 DFP_VAL_PRINT(d, type); \ 138 printf(" -> %d ", D2I(insn, d, type, round, cc)); \ 139 printf("cc=%d\n", cc); \ 140 }) 141 142#define DO_INSN_D2I(insn, round, type) \ 143 ({ \ 144 int cc; \ 145 type d; \ 146 d = -1.1DD; \ 147 DO_PRINT_D2I(insn, d, type, round, cc); \ 148 d = 0.DD; \ 149 DO_PRINT_D2I(insn, d, type, round, cc); \ 150 d = 1.DD; \ 151 DO_PRINT_D2I(insn, d, type, round, cc); \ 152 d = 1.4DD; \ 153 DO_PRINT_D2I(insn, d, type, round, cc); \ 154 d = 1.5DD; \ 155 DO_PRINT_D2I(insn, d, type, round, cc); \ 156 d = 1.6DD; \ 157 DO_PRINT_D2I(insn, d, type, round, cc); \ 158 d = 1.6E+4DD; \ 159 DO_PRINT_D2I(insn, d, type, round, cc); \ 160 d = 1.6E+8DD; \ 161 DO_PRINT_D2I(insn, d, type, round, cc); \ 162 d = 1.6E+4DD; \ 163 DO_PRINT_D2I(insn, d, type, round, cc); \ 164 d = 1.6E+12DD; \ 165 DO_PRINT_D2I(insn, d, type, round, cc); \ 166 d = 1.6E+20DD; \ 167 DO_PRINT_D2I(insn, d, type, round, cc); \ 168 d = 1.6E+200DD; \ 169 DO_PRINT_D2I(insn, d, type, round, cc); \ 170 d = 1.6E-4DD; \ 171 DO_PRINT_D2I(insn, d, type, round, cc); \ 172 d = DEC32_MIN; \ 173 DO_PRINT_D2I(insn, d, type, round, cc); \ 174 d = DEC32_MAX; \ 175 DO_PRINT_D2I(insn, d, type, round, cc); \ 176 d = DEC64_MIN; \ 177 DO_PRINT_D2I(insn, d, type, round, cc); \ 178 d = DEC64_MAX; \ 179 DO_PRINT_D2I(insn, d, type, round, cc); \ 180 }) 181 182#define DO_D2L(round) \ 183 ({ \ 184 DO_INSN_D2L(CLFDTR, round, _Decimal64); \ 185 DO_INSN_D2L(CLGDTR, round, _Decimal64); \ 186 DO_INSN_D2I(CFDTR, round, _Decimal64); \ 187 DO_INSN_D2L(CLFXTR, round, _Decimal128); \ 188 DO_INSN_D2L(CLGXTR, round, _Decimal128); \ 189 DO_INSN_D2I(CFXTR, round, _Decimal128); \ 190 }) 191 192 193int main() 194{ 195 /* rounding mode is not used for the following insns */ 196 DO_INSN_I2D(CDFTR, 0, _Decimal64); 197 DO_INSN_I2D(CXFTR, 0, _Decimal128); 198 DO_INSN_L2D(CDLFTR, 0, _Decimal64); 199 DO_INSN_L2D(CXLFTR, 0, _Decimal128); 200 DO_INSN_L2D(CXLGTR, 0, _Decimal128); 201 202 /* Omit rounding mode value 0 and 2 as the current DFP rounding 203 mode is chosen for these values. */ 204 DO_INSN_L2D(CDLGTR, 1, _Decimal64); 205 DO_D2L(1); 206 207 DO_INSN_L2D(CDLGTR, 3, _Decimal64); 208 DO_D2L(3); 209 210 DO_INSN_L2D(CDLGTR, 4, _Decimal64); 211 DO_D2L(4); 212 213 DO_INSN_L2D(CDLGTR, 5, _Decimal64); 214 DO_D2L(5); 215 216 DO_INSN_L2D(CDLGTR, 6, _Decimal64); 217 DO_D2L(6); 218 219 DO_INSN_L2D(CDLGTR, 7, _Decimal64); 220 DO_D2L(7); 221 222 DO_INSN_L2D(CDLGTR, 8, _Decimal64); 223 DO_D2L(8); 224 225 DO_INSN_L2D(CDLGTR, 9, _Decimal64); 226 DO_D2L(9); 227 228 DO_INSN_L2D(CDLGTR, a, _Decimal64); 229 DO_D2L(a); 230 231 DO_INSN_L2D(CDLGTR, b, _Decimal64); 232 DO_D2L(b); 233 234 DO_INSN_L2D(CDLGTR, c, _Decimal64); 235 DO_D2L(c); 236 237 DO_INSN_L2D(CDLGTR, d, _Decimal64); 238 DO_D2L(d); 239 240 DO_INSN_L2D(CDLGTR, e, _Decimal64); 241 DO_D2L(e); 242 243 DO_INSN_L2D(CDLGTR, f, _Decimal64); 244 DO_D2L(f); 245 246 return 0; 247} 248