#include <stdio.h> #include "opcodes.h" #include "dfp_utils.h" #define __STDC_WANT_DEC_FP__ 1 #include <float.h> #define L2D(insn, initial, target,round) \ ({ \ register unsigned long source asm("2") = initial; \ register typeof(target) _t asm("f0"); \ asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source)); \ _t; \ }) #define I2D(insn, initial, target,round) \ ({ \ register int source asm("2") = initial; \ register typeof(target) _t asm("f0"); \ asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source)); \ _t; \ }) #define D2L(insn, initial, type, round, cc) \ ({ \ register type source asm("f0") = initial; \ register unsigned long target asm ("2") = 0; \ asm volatile(insn(round,0,2,0) \ "ipm %1\n\t" \ "srl %1,28\n\t" \ :"=d" (target), "=d" (cc) :"f"(source):"cc"); \ target; \ }) #define D2I(insn, initial, type, round, cc) \ ({ \ register type source asm("f0") = initial; \ register int target asm ("2") = 0; \ asm volatile(insn(round,0,2,0) \ "ipm %1\n\t" \ "srl %1,28\n\t" \ :"=d" (target), "=d" (cc) :"f"(source):"cc"); \ target; \ }) #define DO_PRINT_L2D(insn, l, d, round) \ ({ \ printf(#insn " round=%d %lu -> ", 0x##round, l); \ d = L2D(insn, l, d, round); \ DFP_VAL_PRINT(d, typeof(d)); \ printf("\n"); \ }) #define DO_INSN_L2D(insn, round, type) \ ({ \ type d; \ DO_PRINT_L2D(insn, 0UL, d, round); \ DO_PRINT_L2D(insn, 1UL, d, round); \ DO_PRINT_L2D(insn, 0xffffffffUL, d, round); \ DO_PRINT_L2D(insn, 0x80000000UL, d, round); \ DO_PRINT_L2D(insn, 0x7fffffffUL, d, round); \ DO_PRINT_L2D(insn, 0x100000000UL, d, round); \ DO_PRINT_L2D(insn, 0xffffffffffffffffUL, d, round); \ DO_PRINT_L2D(insn, 0x8000000000000000UL, d, round); \ DO_PRINT_L2D(insn, 0x7fffffffffffffffUL, d, round); \ }) #define DO_PRINT_I2D(insn, l, d, round) \ ({ \ printf(#insn " round=%d %d -> ", 0x##round, l); \ d = I2D(insn, l, d, round); \ DFP_VAL_PRINT(d, typeof(d)); \ printf("\n"); \ }) #define DO_INSN_I2D(insn, round, type) \ ({ \ type d; \ DO_PRINT_I2D(insn, 0, d, round); \ DO_PRINT_I2D(insn, 1, d, round); \ DO_PRINT_I2D(insn, 0xffffffff, d, round); \ DO_PRINT_I2D(insn, 0x80000000, d, round); \ DO_PRINT_I2D(insn, 0x7fffffff, d, round); \ }) #define DO_PRINT_D2L(insn, d, type, round, cc) \ ({ \ printf(#insn " round=%d ", 0x##round); \ DFP_VAL_PRINT(d, type); \ printf(" -> %lu ", D2L(insn, d, type, round, cc)); \ printf("cc=%d\n", cc); \ }) #define DO_INSN_D2L(insn, round, type) \ ({ \ int cc; \ type d; \ d = -1.1DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 0.DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.4DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.5DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.6DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.6E+4DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.6E+8DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.6E+4DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.6E+12DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.6E+20DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.6E+200DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = 1.6E-4DD; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = DEC32_MIN; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = DEC32_MAX; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = DEC64_MIN; \ DO_PRINT_D2L(insn, d, type, round, cc); \ d = DEC64_MAX; \ DO_PRINT_D2L(insn, d, type, round, cc); \ }) #define DO_PRINT_D2I(insn, d, type, round, cc) \ ({ \ printf(#insn " round=%d ", 0x##round); \ DFP_VAL_PRINT(d, type); \ printf(" -> %d ", D2I(insn, d, type, round, cc)); \ printf("cc=%d\n", cc); \ }) #define DO_INSN_D2I(insn, round, type) \ ({ \ int cc; \ type d; \ d = -1.1DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 0.DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.4DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.5DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.6DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.6E+4DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.6E+8DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.6E+4DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.6E+12DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.6E+20DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.6E+200DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = 1.6E-4DD; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = DEC32_MIN; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = DEC32_MAX; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = DEC64_MIN; \ DO_PRINT_D2I(insn, d, type, round, cc); \ d = DEC64_MAX; \ DO_PRINT_D2I(insn, d, type, round, cc); \ }) #define DO_D2L(round) \ ({ \ DO_INSN_D2L(CLFDTR, round, _Decimal64); \ DO_INSN_D2L(CLGDTR, round, _Decimal64); \ DO_INSN_D2I(CFDTR, round, _Decimal64); \ DO_INSN_D2L(CLFXTR, round, _Decimal128); \ DO_INSN_D2L(CLGXTR, round, _Decimal128); \ DO_INSN_D2I(CFXTR, round, _Decimal128); \ }) int main() { /* rounding mode is not used for the following insns */ DO_INSN_I2D(CDFTR, 0, _Decimal64); DO_INSN_I2D(CXFTR, 0, _Decimal128); DO_INSN_L2D(CDLFTR, 0, _Decimal64); DO_INSN_L2D(CXLFTR, 0, _Decimal128); DO_INSN_L2D(CXLGTR, 0, _Decimal128); /* Omit rounding mode value 0 and 2 as the current DFP rounding mode is chosen for these values. */ DO_INSN_L2D(CDLGTR, 1, _Decimal64); DO_D2L(1); DO_INSN_L2D(CDLGTR, 3, _Decimal64); DO_D2L(3); DO_INSN_L2D(CDLGTR, 4, _Decimal64); DO_D2L(4); DO_INSN_L2D(CDLGTR, 5, _Decimal64); DO_D2L(5); DO_INSN_L2D(CDLGTR, 6, _Decimal64); DO_D2L(6); DO_INSN_L2D(CDLGTR, 7, _Decimal64); DO_D2L(7); DO_INSN_L2D(CDLGTR, 8, _Decimal64); DO_D2L(8); DO_INSN_L2D(CDLGTR, 9, _Decimal64); DO_D2L(9); DO_INSN_L2D(CDLGTR, a, _Decimal64); DO_D2L(a); DO_INSN_L2D(CDLGTR, b, _Decimal64); DO_D2L(b); DO_INSN_L2D(CDLGTR, c, _Decimal64); DO_D2L(c); DO_INSN_L2D(CDLGTR, d, _Decimal64); DO_D2L(d); DO_INSN_L2D(CDLGTR, e, _Decimal64); DO_D2L(e); DO_INSN_L2D(CDLGTR, f, _Decimal64); DO_D2L(f); return 0; }