mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-11 09:56:29 +00:00
377 lines
7.9 KiB
C
377 lines
7.9 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include "dfp_utils.h"
|
|
|
|
/* Test various DFP ops:
|
|
- extract biased exponent 64/128 bit
|
|
- extract significance 64/128 bit
|
|
- insert biased exponent 64/128 bit
|
|
- load and test 64/128 bit
|
|
- shift left/right 64/128 bit
|
|
- reround 64/128 bit
|
|
*/
|
|
|
|
void eedtr(_Decimal64 in)
|
|
{
|
|
long out;
|
|
asm volatile(".insn rre, 0xb3e50000, %[out], %[in]\n\t"
|
|
:[out] "=d" (out) :[in] "f" (in));
|
|
printf("EEDTR ");
|
|
DFP_VAL_PRINT(in, _Decimal64);
|
|
printf(" -> %ld\n", out);
|
|
}
|
|
|
|
void eextr(_Decimal128 in)
|
|
{
|
|
long out;
|
|
asm volatile(".insn rre, 0xb3ed0000, %[out], %[in]\n\t"
|
|
:[out] "=d" (out) :[in] "f" (in));
|
|
printf("EEXTR ");
|
|
DFP_VAL_PRINT(in, _Decimal128);
|
|
printf(" -> %ld\n", out);
|
|
}
|
|
|
|
void esdtr(_Decimal64 in)
|
|
{
|
|
long out;
|
|
asm volatile(".insn rre, 0xb3e70000, %[out], %[in]\n\t"
|
|
:[out] "=d" (out) :[in] "f" (in));
|
|
printf("ESDTR ");
|
|
DFP_VAL_PRINT(in, _Decimal64);
|
|
printf(" -> %ld\n", out);
|
|
}
|
|
|
|
void esxtr(_Decimal128 in)
|
|
{
|
|
long out;
|
|
asm volatile(".insn rre, 0xb3ef0000, %[out], %[in]\n\t"
|
|
:[out] "=d" (out) :[in] "f" (in));
|
|
printf("ESXTR ");
|
|
DFP_VAL_PRINT(in, _Decimal128);
|
|
printf(" -> %ld\n", out);
|
|
}
|
|
|
|
void iedtr(_Decimal64 in, long amount)
|
|
{
|
|
_Decimal64 out;
|
|
|
|
asm volatile (".insn rrf, 0xb3f60000, %[out], %[amount], %[in], 0\n\t"
|
|
:[out]"=f"(out)
|
|
:[in]"f"(in), [amount]"d"(amount));
|
|
|
|
printf("IEDTR ");
|
|
DFP_VAL_PRINT(in, _Decimal64);
|
|
printf(", %ld -> ", amount);
|
|
DFP_VAL_PRINT(out, _Decimal64);
|
|
printf("\n");
|
|
}
|
|
|
|
void iextr(_Decimal128 in, long amount)
|
|
{
|
|
_Decimal128 out;
|
|
|
|
asm volatile (".insn rrf, 0xb3fe0000, %[out], %[amount], %[in], 0\n\t"
|
|
:[out]"=f"(out)
|
|
:[in]"f"(in), [amount]"d"(amount));
|
|
|
|
printf("IEXTR ");
|
|
DFP_VAL_PRINT(in, _Decimal128);
|
|
printf(", %ld -> ", amount);
|
|
DFP_VAL_PRINT(out, _Decimal128);
|
|
printf("\n");
|
|
}
|
|
|
|
void ltdtr(_Decimal64 in)
|
|
{
|
|
_Decimal64 out;
|
|
int cc;
|
|
asm volatile(".insn rre, 0xb3d60000, %[out], %[in]\n\t"
|
|
"ipm %1\n\t"
|
|
"srl %1,28\n\t"
|
|
:[out] "=d" (out), "=d" (cc)
|
|
:[in] "f" (in));
|
|
printf("LTDTR ");
|
|
DFP_VAL_PRINT(in, _Decimal64);
|
|
printf(" -> %d\n", cc);
|
|
}
|
|
|
|
void ltxtr(_Decimal128 in)
|
|
{
|
|
_Decimal128 out;
|
|
int cc;
|
|
asm volatile(".insn rre, 0xb3de0000, %[out], %[in]\n\t"
|
|
"ipm %1\n\t"
|
|
"srl %1,28\n\t"
|
|
:[out] "=f" (out), "=d" (cc)
|
|
:[in] "f" (in));
|
|
printf("LTXTR ");
|
|
DFP_VAL_PRINT(in, _Decimal128);
|
|
printf(" -> %d\n", cc);
|
|
}
|
|
|
|
void qadtr(_Decimal64 op, _Decimal64 quan, uint8_t rm)
|
|
{
|
|
_Decimal64 out;
|
|
|
|
asm volatile (
|
|
".insn rrf, 0xb3f50000, %[out], %[quan], %[op], %[rm]\n\t"
|
|
:[out]"=f"(out)
|
|
:[op]"f"(op), [quan]"f"(quan), [rm]"d"(rm)
|
|
);
|
|
printf("QADTR ");
|
|
DFP_VAL_PRINT(op, _Decimal64);
|
|
printf(", ");
|
|
DFP_VAL_PRINT(quan, _Decimal64);
|
|
printf(", %x -> ", rm);
|
|
DFP_VAL_PRINT(out, _Decimal64);
|
|
printf("\n");
|
|
}
|
|
|
|
void quantize64(_Decimal64 op, _Decimal64 quan)
|
|
{
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
qadtr(op, quan, i);
|
|
}
|
|
|
|
void qaxtr(_Decimal128 op, _Decimal128 quan, uint8_t rm)
|
|
{
|
|
_Decimal128 out;
|
|
|
|
asm volatile (
|
|
".insn rrf, 0xb3fd0000, %[out], %[quan], %[op], %[rm]\n\t"
|
|
:[out]"=f"(out)
|
|
:[op]"f"(op), [quan]"f"(quan), [rm]"d"(rm)
|
|
);
|
|
printf("QAXTR ");
|
|
DFP_VAL_PRINT(op, _Decimal128);
|
|
printf(", ");
|
|
DFP_VAL_PRINT(quan, _Decimal128);
|
|
printf(", %x -> ", rm);
|
|
DFP_VAL_PRINT(out, _Decimal128);
|
|
printf("\n");
|
|
}
|
|
|
|
void quantize128(_Decimal128 op, _Decimal128 quan)
|
|
{
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
qaxtr(op, quan, i);
|
|
}
|
|
|
|
void rrdtr(_Decimal64 op, uint8_t sig, uint8_t rm)
|
|
{
|
|
_Decimal64 out;
|
|
|
|
asm volatile (
|
|
".insn rrf, 0xb3f70000, %[out], %[sig], %[op], %[rm]\n\t"
|
|
:[out]"=f"(out)
|
|
:[op]"f"(op), [sig]"d"(sig), [rm]"d"(rm)
|
|
);
|
|
printf("RRDTR ");
|
|
DFP_VAL_PRINT(op, _Decimal64);
|
|
printf(", %d, %x -> ", sig, rm);
|
|
DFP_VAL_PRINT(out, _Decimal64);
|
|
printf("\n");
|
|
}
|
|
|
|
void reround64(_Decimal64 op, uint8_t sig)
|
|
{
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
rrdtr(op, sig, i);
|
|
}
|
|
|
|
void rrxtr(_Decimal128 op, uint8_t sig, uint8_t rm)
|
|
{
|
|
_Decimal128 out;
|
|
|
|
asm volatile (
|
|
".insn rrf, 0xb3ff0000, %[out], %[sig], %[op], %[rm]\n\t"
|
|
:[out]"=f"(out)
|
|
:[op]"f"(op), [sig]"d"(sig), [rm]"d"(rm)
|
|
);
|
|
printf("RRXTR ");
|
|
DFP_VAL_PRINT(op, _Decimal128);
|
|
printf(", %d, %x -> ", sig, rm);
|
|
DFP_VAL_PRINT(out, _Decimal128);
|
|
printf("\n");
|
|
}
|
|
|
|
void reround128(_Decimal128 op, uint8_t sig)
|
|
{
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
rrxtr(op, sig, i);
|
|
}
|
|
|
|
void sldt(_Decimal64 in, unsigned long amount)
|
|
{
|
|
_Decimal64 out;
|
|
int *shift = (int *) amount;
|
|
|
|
asm volatile (".insn rxf, 0xed0000000040, %[out], %[in], 0(%[amount])\n\t"
|
|
:[out]"=f"(out)
|
|
:[in]"f"(in),[amount]"a"(shift));
|
|
|
|
printf("SLDT ");
|
|
DFP_VAL_PRINT(in, _Decimal64);
|
|
printf(" -> ");
|
|
DFP_VAL_PRINT(out, _Decimal64);
|
|
printf("\n");
|
|
}
|
|
|
|
void slxt(_Decimal128 in, unsigned long amount)
|
|
{
|
|
_Decimal128 out;
|
|
int *shift = (int *) amount;
|
|
|
|
asm volatile (".insn rxf, 0xed0000000048, %[out], %[in], 0(%[amount])\n\t"
|
|
:[out]"=f"(out)
|
|
:[in]"f"(in),[amount]"a"(shift));
|
|
|
|
printf("SLXT ");
|
|
DFP_VAL_PRINT(in, _Decimal128);
|
|
printf(" -> ");
|
|
DFP_VAL_PRINT(out, _Decimal128);
|
|
printf("\n");
|
|
}
|
|
|
|
void srdt(_Decimal64 in, unsigned long amount)
|
|
{
|
|
_Decimal64 out;
|
|
int *shift = (int *) amount;
|
|
|
|
asm volatile (".insn rxf, 0xed0000000041, %[out], %[in], 0(%[amount])\n\t"
|
|
:[out]"=f"(out)
|
|
:[in]"f"(in),[amount]"a"(shift));
|
|
|
|
printf("SRDT ");
|
|
DFP_VAL_PRINT(in, _Decimal64);
|
|
printf(" -> ");
|
|
DFP_VAL_PRINT(out, _Decimal64);
|
|
printf("\n");
|
|
}
|
|
|
|
void srxt(_Decimal128 in, unsigned long amount)
|
|
{
|
|
_Decimal128 out;
|
|
int *shift = (int *) amount;
|
|
|
|
asm volatile (".insn rxf, 0xed0000000049, %[out], %[in], 0(%[amount])\n\t"
|
|
:[out]"=f"(out)
|
|
:[in]"f"(in),[amount]"a"(shift));
|
|
|
|
printf("SRXT ");
|
|
DFP_VAL_PRINT(in, _Decimal128);
|
|
printf(" -> ");
|
|
DFP_VAL_PRINT(out, _Decimal128);
|
|
printf("\n");
|
|
}
|
|
|
|
int main() {
|
|
_Decimal64 d64 = 50.0005DD;
|
|
_Decimal128 d128 = 50.0005DL;
|
|
|
|
eedtr(d64);
|
|
eedtr(-d64);
|
|
eedtr(0.DD);
|
|
eextr(d128);
|
|
eextr(-d128);
|
|
eextr(0.DL);
|
|
|
|
esdtr(d64);
|
|
esdtr(-d64);
|
|
esdtr(0.DD);
|
|
esxtr(d128);
|
|
esxtr(-d128);
|
|
esxtr(0.DL);
|
|
|
|
ltdtr(d64);
|
|
ltdtr(-d64);
|
|
ltdtr(0.0DD);
|
|
ltxtr(d128);
|
|
ltxtr(-d128);
|
|
ltxtr(0.0DL);
|
|
|
|
d64 = 12345678.54321DD;
|
|
sldt(d64, 10);
|
|
sldt(-d64, 2);
|
|
sldt(0.DD, 2);
|
|
sldt(-0.DD, 2);
|
|
|
|
srdt(d64, 5);
|
|
srdt(-d64, 2);
|
|
srdt(0.DD, 2);
|
|
srdt(-0.DD, 2);
|
|
|
|
d128 = 12345678.54321DL;
|
|
slxt(d128, 10);
|
|
slxt(-d128, 2);
|
|
slxt(0.DL, 2);
|
|
slxt(-0.DL, 2);
|
|
|
|
srxt(d128, 10);
|
|
srxt(-d128, 2);
|
|
srxt(0.DL, 2);
|
|
srxt(-0.DL, 2);
|
|
|
|
d64 = 5.000005DD;
|
|
iedtr(d64, 391);
|
|
iedtr(d64, 392);
|
|
iedtr(d64, 393);
|
|
iedtr(-d64, 391);
|
|
iedtr(-d64, 392);
|
|
iedtr(-d64, 393);
|
|
iedtr(0.DD, 393);
|
|
iedtr(-0.DD, 393);
|
|
iedtr(1.DD, 393);
|
|
|
|
d128 = 5.000005DL;
|
|
iextr(d128, 6169);
|
|
iextr(d128, 6170);
|
|
iextr(d128, 6171);
|
|
iextr(-d128, 6169);
|
|
iextr(-d128, 6170);
|
|
iextr(-d128, 6171);
|
|
iextr(0.DL, 6171);
|
|
iextr(-0.DL, 6171);
|
|
iextr(1.DL, 6171);
|
|
|
|
d64 = 2.171234DD;
|
|
quantize64(d64, 0.001DD);
|
|
quantize64(-d64, 0.001DD);
|
|
quantize64(-d64, 0.DD);
|
|
quantize64(0.DD, 0.001DD);
|
|
|
|
d128 = 26365343648.171234DL;
|
|
quantize128(d128, 230.01DL);
|
|
quantize128(-d128, 230.01DL);
|
|
quantize128(d128, 0.DL);
|
|
quantize128(-0.DL, 230.01DL);
|
|
|
|
d64 = 2.174598DD;
|
|
reround64(d64, 3);
|
|
reround64(d64, 4);
|
|
reround64(d64, 5);
|
|
reround64(-d64, 3);
|
|
reround64(-d64, 4);
|
|
reround64(-d64, 5);
|
|
reround64(0.DD, 0);
|
|
|
|
d128 = 2.174598DL;
|
|
reround128(d128, 3);
|
|
reround128(d128, 4);
|
|
reround128(d128, 5);
|
|
reround128(-d128, 3);
|
|
reround128(-d128, 4);
|
|
reround128(-d128, 5);
|
|
reround128(0.DL, 0);
|
|
|
|
return 0;
|
|
}
|