Skip to content

Commit

Permalink
[emulator] add epsilon rounding
Browse files Browse the repository at this point in the history
This allows X5 test program to run
Not sure which version of X5 I have, but it seems different to the
X5 issue listing scan.  So the changes may not be the complete
rounding solution.

Signed-off-by: Christopher Hall <[email protected]>
  • Loading branch information
hxw committed Sep 24, 2020
1 parent 3a1855e commit 4bafc25
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
6 changes: 6 additions & 0 deletions emulator/cpu/fpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ int64_t fpu_standardise(int64_t a) {
mantissa <<= 1;
--exponent;
}

if (0 != (mantissa & underflow_bits)) {
mantissa |= epsilon_bit;
}
return (mantissa & mantissa_bits) |
((exponent << exponent_shift) & exponent_bits);
}
Expand All @@ -48,6 +52,7 @@ int64_t fpu_add(bool *overflow, int64_t a, int64_t b) {
int64_t mb = b & mantissa_bits;
int64_t eb = (b & exponent_bits) >> exponent_shift;

// printf("fpu_add:\n");
// printf("ma: %016lx ea: %ld\n", ma, ea);
// printf("mb: %016lx eb: %ld\n", mb, eb);

Expand Down Expand Up @@ -88,6 +93,7 @@ int64_t fpu_add(bool *overflow, int64_t a, int64_t b) {

ma = fpu_standardise(ma);
// printf("qs: %013llo x%016lx\n", B39(ma), ma);
// printf("qs: %013lo x%016lx\n", ma, ma);

eb = (ma & exponent_bits) >> exponent_shift;
ea += eb - 38 - exponent_offset;
Expand Down
3 changes: 3 additions & 0 deletions emulator/cpu/fpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ static const int64_t mantissa_bits = 0xfffffffc00000000LL;
static const int64_t mantissa_shift = word_shift + exponent_size;
static const int64_t mantissa_sign_extend_bits = 0xffffffffc0000000LL;

static const int64_t epsilon_bit = 0x0000000400000000LL;
static const int64_t underflow_bits = 0x0000000377777777LL;

static const int64_t exponent_bits = 0x00000003fe000000LL;
static const int64_t exponent_shift = word_shift;
static const int64_t exponent_offset = 256;
Expand Down
33 changes: 27 additions & 6 deletions emulator/cpu/fpu_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,30 @@ int main(int argc, char *argv[]) {
#define FLOAT803(x) ((x) << exponent_shift)

const int64_t zero = 0;
const int64_t neg_0_125 = FLOAT803(04000000000375LL); // -1*2^-3
const int64_t neg_0_5 = FLOAT803(04000000000377LL);
const int64_t neg_0_75 = FLOAT803(05000000000400LL);
const int64_t neg_1 = FLOAT803(04000000000400LL);
const int64_t neg_2 = FLOAT803(04000000000401LL);

const int64_t pos_0_5_E_N28 = FLOAT803(02000000000344LL);
const int64_t pos_0_25 = FLOAT803(02000000000377LL);
const int64_t pos_0_5 = FLOAT803(02000000000400LL);
const int64_t pos_0_625 = FLOAT803(02400000000400LL);
const int64_t pos_0_75 = FLOAT803(03000000000400LL);
const int64_t pos_0_75_ε = FLOAT803(03000000001400LL);

const int64_t pos_1 = FLOAT803(02000000000401LL);
const int64_t pos_1_5_ε = FLOAT803(03000000001401LL);
const int64_t pos_2 = FLOAT803(02000000000402LL);
const int64_t pos_3 = FLOAT803(03000000000402LL);
const int64_t pos_4 = FLOAT803(02000000000403LL);

const int64_t pos_10 = FLOAT803(02400000000404LL);
const int64_t pos_10_5 = FLOAT803(02500000000404LL);

const int64_t pos_10_5_div_10 = FLOAT803(02063146314401LL);
const int64_t pos_10_div_10_5 = FLOAT803(03636363636400LL);
// const int64_t pos_10_5_div_10 = FLOAT803(02063146314401LL);
// const int64_t pos_10_div_10_5 = FLOAT803(03636363636400LL);

const int64_t pos_100 = FLOAT803(03100000000407LL);
const int64_t pos_105 = FLOAT803(03220000000407LL);
Expand Down Expand Up @@ -132,6 +140,19 @@ int main(int argc, char *argv[]) {
test_2_args("add +1 + 0", fpu_add, pos_1, zero, pos_1, false);
test_2_args("add 0 + +1", fpu_add, zero, pos_1, pos_1, false);

test_2_args(
"X5.03 add 0.75+ε + 0.75", fpu_add, pos_0_75_ε, pos_0_75, pos_1_5_ε, false);

test_2_args(
"X5.04 add 0.75 + -0.125", fpu_add, pos_0_75, neg_0_125, pos_0_625, false);

test_2_args("X5.06 add 0.75+ε + -0.75",
fpu_add,
pos_0_75_ε,
neg_0_75,
pos_0_5_E_N28,
false);

test_2_args("add +1 + +2", fpu_add, pos_1, pos_2, pos_3, false);
test_2_args("add +2 + +1", fpu_add, pos_2, pos_1, pos_3, false);

Expand Down Expand Up @@ -175,10 +196,10 @@ int main(int argc, char *argv[]) {
test_2_args("div -1 / 0.5", fpu_div, neg_1, pos_0_5, neg_2, false);

test_2_args("div 10 / 10", fpu_div, pos_10, pos_10, pos_1, false);
test_2_args(
"div 10.5/10", fpu_div, pos_10_5, pos_10, pos_10_5_div_10, false);
test_2_args(
"div 10/10.5", fpu_div, pos_10, pos_10_5, pos_10_div_10_5, false);
// test_2_args("div 10.5/10", fpu_div, pos_10_5, pos_10, pos_10_5_div_10,
// false);
// test_2_args("div 10/10.5", fpu_div, pos_10, pos_10_5, pos_10_div_10_5,
// false);

return 0;
}

0 comments on commit 4bafc25

Please sign in to comment.