mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-11 09:56:29 +00:00
248 lines
13 KiB
C
248 lines
13 KiB
C
#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;
|
|
}
|