#include <stdio.h>
#include "opcodes.h"
#include "dfp_utils.h"
#define __STDC_WANT_DEC_FP__ 1
#include <float.h>
#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 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_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_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_D2I(round) \
({ \
DO_INSN_D2I(CGDTRA, round, _Decimal64); \
DO_INSN_D2I(CGXTRA, round, _Decimal128); \
})
int main()
{
/* rounding mode is not used for the I64 -> D128 conversion */
DO_INSN_I2D(CXGTRA, 0, _Decimal128);
/* Omit rounding mode value 0 and 2 as the current DFP rounding
mode is chosen for these values. */
DO_INSN_I2D(CDGTRA, 1, _Decimal64);
DO_D2I(1);
DO_INSN_I2D(CDGTRA, 3, _Decimal64);
DO_D2I(3);
DO_INSN_I2D(CDGTRA, 4, _Decimal64);
DO_D2I(4);
DO_INSN_I2D(CDGTRA, 5, _Decimal64);
DO_D2I(5);
DO_INSN_I2D(CDGTRA, 6, _Decimal64);
DO_D2I(6);
DO_INSN_I2D(CDGTRA, 7, _Decimal64);
DO_D2I(7);
DO_INSN_I2D(CDGTRA, 8, _Decimal64);
DO_D2I(8);
DO_INSN_I2D(CDGTRA, 9, _Decimal64);
DO_D2I(9);
DO_INSN_I2D(CDGTRA, a, _Decimal64);
DO_D2I(a);
DO_INSN_I2D(CDGTRA, b, _Decimal64);
DO_D2I(b);
DO_INSN_I2D(CDGTRA, c, _Decimal64);
DO_D2I(c);
DO_INSN_I2D(CDGTRA, d, _Decimal64);
DO_D2I(d);
DO_INSN_I2D(CDGTRA, e, _Decimal64);
DO_D2I(e);
DO_INSN_I2D(CDGTRA, f, _Decimal64);
DO_D2I(f);
return 0;
}