mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-11 09:56:29 +00:00
274 lines
9.1 KiB
C
274 lines
9.1 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include "dfp_utils.h"
|
|
#define __STDC_WANT_DEC_FP__ 1
|
|
#include <float.h>
|
|
|
|
#ifndef PFPO_FUNCTIONS
|
|
#define PFPO_FUNCTIONS
|
|
#define PFPO_F32_TO_D32 0x01080500
|
|
#define PFPO_D32_TO_F32 0x01050800
|
|
#define PFPO_F32_TO_D64 0x01090500
|
|
#define PFPO_D32_TO_F64 0x01060800
|
|
#define PFPO_F32_TO_D128 0x010A0500
|
|
#define PFPO_D32_TO_F128 0x01070800
|
|
#define PFPO_F64_TO_D32 0x01080600
|
|
#define PFPO_D64_TO_F32 0x01050900
|
|
#define PFPO_F64_TO_D64 0x01090600
|
|
#define PFPO_D64_TO_F64 0x01060900
|
|
#define PFPO_F64_TO_D128 0x010A0600
|
|
#define PFPO_D64_TO_F128 0x01070900
|
|
#define PFPO_D128_TO_F64 0x01060A00
|
|
#define PFPO_F128_TO_D32 0x01080700
|
|
#define PFPO_D128_TO_F32 0x01050A00
|
|
#define PFPO_F128_TO_D64 0x01090700
|
|
#define PFPO_D128_TO_F64 0x01060A00
|
|
#define PFPO_F128_TO_D128 0x010A0700
|
|
#define PFPO_D128_TO_F128 0x01070A00
|
|
|
|
#define PFPO(initial, src_type, dst_type, fn_code, round, ret_code, cc) \
|
|
({ \
|
|
register src_type src_reg asm("f4") = initial; \
|
|
register dst_type dst_reg asm("f0"); \
|
|
register unsigned long fn asm("0") = fn_code | (round & 0xf); \
|
|
register unsigned int ret asm("1"); \
|
|
asm volatile(".short 0x010a\n\t" \
|
|
"ipm %2\n\t" \
|
|
"srl %2,28\n\t" \
|
|
:"=f"(dst_reg), "=d"(ret), "=d" (cc) \
|
|
: "f"(src_reg), "d"(fn)); \
|
|
ret_code = ret; \
|
|
dst_reg; \
|
|
})
|
|
|
|
#endif /* PFPO_FUNCTIONS */
|
|
|
|
/* Test BFP <-> DFP conversions */
|
|
int main()
|
|
{
|
|
int cc;
|
|
uint8_t i, j;
|
|
unsigned int ret_code;
|
|
|
|
float f32;
|
|
double f64;
|
|
long double f128;
|
|
|
|
_Decimal32 d32;
|
|
_Decimal64 d64;
|
|
_Decimal128 d128;
|
|
|
|
float f32_in[] = {123.5656789, FLT_MAX, FLT_MIN};
|
|
double f64_in[] = {123456789999.5656789, DBL_MIN, DBL_MAX};
|
|
long double f128_in[] = {1234567812345678912345678912.5656789L,
|
|
LDBL_MIN, LDBL_MAX};
|
|
|
|
_Decimal32 d32_in[] = {123.5656789DF, DEC32_MAX, DEC32_MIN};
|
|
_Decimal64 d64_in[] = {123456789999.5656789DD, DEC64_MIN, DEC64_MAX};
|
|
_Decimal128 d128_in[] = {1234567812345678912345678912.5656789DL,
|
|
DEC128_MIN, DEC128_MAX};
|
|
|
|
/* valid function code */
|
|
PFPO(0., double, _Decimal64, 0x81090600, 0, ret_code, cc);
|
|
printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81090600, ret_code, cc);
|
|
|
|
/* invalid function code */
|
|
PFPO(0., double, _Decimal64, 0x81990600, 0, ret_code, cc);
|
|
printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81990600, ret_code, cc);
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
if (i < 2 || i > 7) {
|
|
|
|
/* f32 -> d32 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("f32 -> d32: round=%x ", i);
|
|
printf("%f -> ", f32_in[j]);
|
|
d32 = PFPO(f32_in[j], float, _Decimal32, PFPO_F32_TO_D32,
|
|
i, ret_code, cc);
|
|
DFP_VAL_PRINT(d32, _Decimal32);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* f32 -> d64 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("f32 -> d64: round=%x ", i);
|
|
printf("%f -> ", f32_in[j]);
|
|
d64 = PFPO(f32_in[j], float, _Decimal64, PFPO_F32_TO_D64,
|
|
i, ret_code, cc);
|
|
DFP_VAL_PRINT(d64, _Decimal64);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* f32 -> d128 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("f32 -> d128: round=%x ", i);
|
|
printf("%f -> ", f32_in[j]);
|
|
d128 = PFPO(f32_in[j], float, _Decimal128, PFPO_F32_TO_D128,
|
|
i, ret_code, cc);
|
|
DFP_VAL_PRINT(d128, _Decimal128);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* f64 -> d32 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("f64 -> d32: round=%x ", i);
|
|
printf("%lf -> ", f64_in[j]);
|
|
d32 = PFPO(f64_in[j], double, _Decimal32, PFPO_F64_TO_D32,
|
|
i, ret_code, cc);
|
|
DFP_VAL_PRINT(d32, _Decimal32);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* f64 -> d64 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("f64 -> d64: round=%x ", i);
|
|
printf("%lf -> ", f64_in[j]);
|
|
d64 = PFPO(f64_in[j], double, _Decimal64, PFPO_F64_TO_D64,
|
|
i, ret_code, cc);
|
|
DFP_VAL_PRINT(d64, _Decimal64);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* f64 -> d128 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("f64 -> d128: round=%x ", i);
|
|
printf("%lf -> ", f64_in[j]);
|
|
d128 = PFPO(f64_in[j], double, _Decimal128, PFPO_F64_TO_D128,
|
|
i, ret_code, cc);
|
|
DFP_VAL_PRINT(d128, _Decimal128);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* f128 -> d32 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("f128 -> d32: round=%x ", i);
|
|
printf("%Lf -> ", f128_in[j]);
|
|
d32 = PFPO(f128_in[j], long double, _Decimal32, PFPO_F128_TO_D32,
|
|
i, ret_code, cc);
|
|
DFP_VAL_PRINT(d32, _Decimal32);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* f128 -> d64 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("f128 -> d6: round=%x ", i);
|
|
printf("%Lf -> ", f128_in[j]);
|
|
d64 = PFPO(f128_in[j], long double, _Decimal64, PFPO_F128_TO_D64,
|
|
i, ret_code, cc);
|
|
DFP_VAL_PRINT(d64, _Decimal64);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* f128 -> d128 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("f128 -> d128: round=%x ", i);
|
|
printf("%Lf -> ", f128_in[j]);
|
|
d128 = PFPO(f128_in[j], long double, _Decimal128, PFPO_F128_TO_D128,
|
|
i, ret_code, cc);
|
|
DFP_VAL_PRINT(d128, _Decimal128);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* d32 -> f32 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("d32 -> f32: round=%x ", i);
|
|
DFP_VAL_PRINT(d32_in[j], _Decimal32);
|
|
printf(" -> ");
|
|
f32 = PFPO(d32_in[j], _Decimal32, float, PFPO_D32_TO_F32,
|
|
i, ret_code, cc);
|
|
printf("%f", f32);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* d32 -> f64 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("d32 -> f64: round=%x ", i);
|
|
DFP_VAL_PRINT(d32_in[j], _Decimal32);
|
|
printf(" -> ");
|
|
f64 = PFPO(d32_in[j], _Decimal32, double, PFPO_D32_TO_F64,
|
|
i, ret_code, cc);
|
|
printf("%lf", f64);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* d32 -> f128 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("d32 -> f128: round=%x ", i);
|
|
DFP_VAL_PRINT(d32_in[j], _Decimal32);
|
|
printf(" -> ");
|
|
f128 = PFPO(d32_in[j], _Decimal32, long double, PFPO_D32_TO_F128,
|
|
i, ret_code, cc);
|
|
printf("%Lf", f128);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* d64 -> f32 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("d64 -> f32: round=%x ", i);
|
|
DFP_VAL_PRINT(d64_in[j], _Decimal64);
|
|
printf(" -> ");
|
|
f32 = PFPO(d64_in[j], _Decimal64, float, PFPO_D64_TO_F32,
|
|
i, ret_code, cc);
|
|
printf("%f", f32);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* d64 -> f64 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("d64 -> f64: round=%x ", i);
|
|
DFP_VAL_PRINT(d64_in[j], _Decimal64);
|
|
printf(" -> ");
|
|
f64 = PFPO(d64_in[j], _Decimal64, double, PFPO_D64_TO_F64,
|
|
i, ret_code, cc);
|
|
printf("%lf", f64);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* d64 -> f128 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("d64 -> f128: round=%x ", i);
|
|
DFP_VAL_PRINT(d64_in[j], _Decimal64);
|
|
printf(" -> ");
|
|
f128 = PFPO(d64_in[j], _Decimal64, long double, PFPO_D64_TO_F128,
|
|
i, ret_code, cc);
|
|
printf("%Lf", f128);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* d128 -> f32 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("d128 -> f32: round=%x ", i);
|
|
DFP_VAL_PRINT(d128_in[j], _Decimal128);
|
|
printf(" -> ");
|
|
f32 = PFPO(d128_in[j], _Decimal128, float, PFPO_D128_TO_F32,
|
|
i, ret_code, cc);
|
|
printf("%f", f32);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* d128 -> f64 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("d128 -> f64: round=%x ", i);
|
|
DFP_VAL_PRINT(d128_in[j], _Decimal128);
|
|
printf(" -> ");
|
|
f64 = PFPO(d128_in[j], _Decimal128, double, PFPO_D128_TO_F64,
|
|
i, ret_code, cc);
|
|
printf("%lf", f64);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
|
|
/* d128 -> f128 */
|
|
for(j = 0; j < 3; j++) {
|
|
printf("d128 -> f128: round=%x ", i);
|
|
DFP_VAL_PRINT(d128_in[j], _Decimal128);
|
|
printf(" -> ");
|
|
f128 = PFPO(d128_in[j], _Decimal128, long double, PFPO_D128_TO_F128,
|
|
i, ret_code, cc);
|
|
printf("%Lf", f128);
|
|
printf(" ret=%d cc=%d\n", ret_code, cc);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|