mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-04-20 10:52:18 +02:00
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:
184
dfp.c
184
dfp.c
@@ -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
50
tests/srdt.txt
Normal 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
|
||||
Reference in New Issue
Block a user