Decimal Floating Point: SLXT,SLDT,SRDT instructions

git-svn-id: file:///home/jj/hercules.svn/trunk@4261 956126f8-22a0-4046-8f4a-272fa8102e63
This commit is contained in:
Roger Bowler
2007-01-22 13:49:10 +00:00
parent 6d2c82e4aa
commit 2d7a493994
2 changed files with 231 additions and 3 deletions

184
dfp.c
View File

@@ -10,6 +10,9 @@
/*-------------------------------------------------------------------*/
// $Log$
// Revision 1.47 2007/01/20 22:22:42 rbowler
// Decimal Floating Point: SRXT instruction (part 2)
//
// Revision 1.46 2007/01/19 15:46:33 rbowler
// Decimal Floating Point: SRXT instruction (part 1)
//
@@ -2654,8 +2657,125 @@ BYTE dxc; /* Data exception code */
} /* end DEF_INST(set_fpc_and_signal) */
UNDEF_INST(shift_coefficient_left_dfp_ext)
UNDEF_INST(shift_coefficient_left_dfp_long)
/*-------------------------------------------------------------------*/
/* ED48 SLXT - Shift Coefficient Left DFP Extended [RXF] */
/*-------------------------------------------------------------------*/
DEF_INST(shift_coefficient_left_dfp_ext)
{
int r1, r3; /* Values of R fields */
int b2; /* Base of effective addr */
VADR effective_addr2; /* Effective address */
decimal128 x1, x3; /* Extended DFP values */
decNumber d1, d3; /* Working decimal numbers */
decContext set; /* Working context */
int n; /* Number of bits to shift */
RXF(inst, regs, r1, r3, b2, effective_addr2);
DFPINST_CHECK(regs);
DFPREGPAIR2_CHECK(r1, r3, regs);
/* Isolate rightmost 6 bits of second operand address */
n = effective_addr2 & 0x3F;
/* Initialise the context for extended DFP */
decContextDefault(&set, DEC_INIT_DECIMAL128);
/* Load DFP extended number from FP register r3 */
ARCH_DEP(dfp_reg_to_decimal128)(r3, &x3, regs);
/* Convert to internal decimal number format */
decimal128ToNumber(&x3, &d3);
/* For NaN and Inf use coefficient continuation digits only */
if (decNumberIsNaN(&d3) || decNumberIsInfinite(&d3))
{
dfp128_clear_cf_and_bxcf(&x3);
decimal128ToNumber(&x3, &d1);
}
else
{
decNumberCopy(&d1, &d3);
}
/* Shift coefficient left n digit positions */
dfp_shift_coeff(&set, &d1, n);
/* Convert result to DFP extended format */
decimal128FromNumber(&x1, &d1, &set);
/* Restore Nan or Inf indicators in the result */
if (decNumberIsQNaN(&d3))
dfp128_set_cf_and_bxcf(&x1, DFP_CFS_QNAN);
else if (decNumberIsSNaN(&d3))
dfp128_set_cf_and_bxcf(&x1, DFP_CFS_SNAN);
else if (decNumberIsInfinite(&d3))
dfp128_set_cf_and_bxcf(&x1, DFP_CFS_INF);
/* Load result into FP register r1 */
ARCH_DEP(dfp_reg_from_decimal128)(r1, &x1, regs);
} /* end DEF_INST(shift_coefficient_left_dfp_ext) */
/*-------------------------------------------------------------------*/
/* ED40 SLDT - Shift Coefficient Left DFP Long [RXF] */
/*-------------------------------------------------------------------*/
DEF_INST(shift_coefficient_left_dfp_long)
{
int r1, r3; /* Values of R fields */
int b2; /* Base of effective addr */
VADR effective_addr2; /* Effective address */
decimal64 x1, x3; /* Long DFP values */
decNumber d1, d3; /* Working decimal numbers */
decContext set; /* Working context */
int n; /* Number of bits to shift */
RXF(inst, regs, r1, r3, b2, effective_addr2);
DFPINST_CHECK(regs);
/* Isolate rightmost 6 bits of second operand address */
n = effective_addr2 & 0x3F;
/* Initialise the context for long DFP */
decContextDefault(&set, DEC_INIT_DECIMAL64);
/* Load DFP long number from FP register r3 */
ARCH_DEP(dfp_reg_to_decimal64)(r3, &x3, regs);
/* Convert to internal decimal number format */
decimal64ToNumber(&x3, &d3);
/* For NaN and Inf use coefficient continuation digits only */
if (decNumberIsNaN(&d3) || decNumberIsInfinite(&d3))
{
dfp64_clear_cf_and_bxcf(&x3);
decimal64ToNumber(&x3, &d1);
}
else
{
decNumberCopy(&d1, &d3);
}
/* Shift coefficient left n digit positions */
dfp_shift_coeff(&set, &d1, n);
/* Convert result to DFP long format */
decimal64FromNumber(&x1, &d1, &set);
/* Restore Nan or Inf indicators in the result */
if (decNumberIsQNaN(&d3))
dfp64_set_cf_and_bxcf(&x1, DFP_CFS_QNAN);
else if (decNumberIsSNaN(&d3))
dfp64_set_cf_and_bxcf(&x1, DFP_CFS_SNAN);
else if (decNumberIsInfinite(&d3))
dfp64_set_cf_and_bxcf(&x1, DFP_CFS_INF);
/* Load result into FP register r1 */
ARCH_DEP(dfp_reg_from_decimal64)(r1, &x1, regs);
} /* end DEF_INST(shift_coefficient_left_dfp_long) */
/*-------------------------------------------------------------------*/
/* ED49 SRXT - Shift Coefficient Right DFP Extended [RXF] */
/*-------------------------------------------------------------------*/
@@ -2716,7 +2836,65 @@ int n; /* Number of bits to shift */
} /* end DEF_INST(shift_coefficient_right_dfp_ext) */
UNDEF_INST(shift_coefficient_right_dfp_long)
/*-------------------------------------------------------------------*/
/* ED41 SRDT - Shift Coefficient Right DFP Long [RXF] */
/*-------------------------------------------------------------------*/
DEF_INST(shift_coefficient_right_dfp_long)
{
int r1, r3; /* Values of R fields */
int b2; /* Base of effective addr */
VADR effective_addr2; /* Effective address */
decimal64 x1, x3; /* Long DFP values */
decNumber d1, d3; /* Working decimal numbers */
decContext set; /* Working context */
int n; /* Number of bits to shift */
RXF(inst, regs, r1, r3, b2, effective_addr2);
DFPINST_CHECK(regs);
/* Isolate rightmost 6 bits of second operand address */
n = effective_addr2 & 0x3F;
/* Initialise the context for long DFP */
decContextDefault(&set, DEC_INIT_DECIMAL64);
/* Load DFP long number from FP register r3 */
ARCH_DEP(dfp_reg_to_decimal64)(r3, &x3, regs);
/* Convert to internal decimal number format */
decimal64ToNumber(&x3, &d3);
/* For NaN and Inf use coefficient continuation digits only */
if (decNumberIsNaN(&d3) || decNumberIsInfinite(&d3))
{
dfp64_clear_cf_and_bxcf(&x3);
decimal64ToNumber(&x3, &d1);
}
else
{
decNumberCopy(&d1, &d3);
}
/* Shift coefficient right n digit positions */
dfp_shift_coeff(&set, &d1, -n);
/* Convert result to DFP long format */
decimal64FromNumber(&x1, &d1, &set);
/* Restore Nan or Inf indicators in the result */
if (decNumberIsQNaN(&d3))
dfp64_set_cf_and_bxcf(&x1, DFP_CFS_QNAN);
else if (decNumberIsSNaN(&d3))
dfp64_set_cf_and_bxcf(&x1, DFP_CFS_SNAN);
else if (decNumberIsInfinite(&d3))
dfp64_set_cf_and_bxcf(&x1, DFP_CFS_INF);
/* Load result into FP register r1 */
ARCH_DEP(dfp_reg_from_decimal64)(r1, &x1, regs);
} /* end DEF_INST(shift_coefficient_right_dfp_long) */
/*-------------------------------------------------------------------*/
/* B3DB SXTR - Subtract DFP Extended Register [RRR] */
/*-------------------------------------------------------------------*/

50
tests/srdt.txt Normal file
View File

@@ -0,0 +1,50 @@
* SRDT test $Id$
sysclear
archmode esame
r 1a0=00000001800000000000000000000200 # z/Arch restart PSW
r 1d0=0002000180000000000000000000DEAD # z/Arch pgm new PSW
r 200=B7000310 # LCTL R0,R0,CTLR0 Set CR0 bit 45
r 204=41000006 # LA R0,6 R0=Number of test data
r 208=41100380 # LA R1,TEST1 R1=>Test data table
r 20C=41F00400 # LA R15,RES1 R15=>Result table
r 210=68601000 #A LD F6,0(,R1) Load FPR6=TESTn
r 214=41200004 # LA R2,4 R2=Number of shift tests
r 218=41300318 # LA R3,N1 R3=>Shift count table
r 21C=58403000 #B L R4,0(,R3) Load R4=Nn
r 220=ED6040008040 # SLDT F8,F6,0 Shift FPR6 left Nn digits
r 226=6080F000 # STD F8,0(,R15) Store F8 in result table
r 22A=41F0F008 # LA R15,8(,R15) R15=>next result table
r 22E=B3E301E8 # CSDTR R14,F8,1 Convert to PACKED R14 from FPR8
r 232=E3E0F0000024 # STG R14,0(,R15) Store R14 in result table
r 238=41F0F008 # LA R15,8(,R15) R15=>next result table
r 23C=ED6040008041 # SRDT F8,F6,0 Shift FPR6 right Nn digits
r 242=6080F000 # STD F8,0(,R15) Store F8 in result table
r 246=41F0F008 # LA R15,8(,R15) R15=>next result table
r 24A=B3E301E8 # CSDTR R14,F8,1 Convert to PACKED R14 from FPR8
r 24E=E3E0F0000024 # STG R14,0(,R15) Store R14 in result table
r 254=41F0F008 # LA R15,8(,R15) R15=>next result table
r 258=41303004 # LA R3,4(,R3) R3=>Next Nn
r 25C=4620021C # BCT R2,B Loop to end of Nn table
r 260=41101008 # LA R1,8(,R1) R1=>Next TESTn
r 264=46000210 # BCT R0,A Loop to end of TESTn table
r 268=B2B20300 # LPSWE WAITPSW Load enabled wait PSW
r 300=07020001800000000000000000FED0D0 # WAITPSW Enabled wait state PSW
r 310=00040000 # CTLR0 Control register 0 (bit45 AFP control)
r 314=00000000 # FPCREG Floating point control register
r 318=00000000 # N1 DC F'0' Shift count 0
r 31C=FFFFFFC1 # N2 DC F'1' Shift count 1
r 320=000002C4 # N3 DC F'708' Shift count 4
r 324=0000003F # N4 DC F'63' Shift count 63
r 380=2238000000000000 # TEST1 DC DD'0' Zero positive
r 388=2238000012045078 # TEST2 DC DD'12045078' Normal positive
r 390=ABCDEF0123456789 # TEST3 DC DD'2.989004434259709E116' Large positive
r 398=7CABCDEF01234567 # TEST4 DC DD'QNAN' QNaN positive
r 3A0=FE0000000000ABCD # TEST5 DC DD'-SNAN' SNaN negative
r 3A8=78123456789ABCDE # TEST6 DC DD'INF' Infinity positive
restart
pause 1
* Display test data
r 318.10
r 380.30
* Display results
r 400.300