hercules-390 / hyperion

Hercules 390
Other
252 stars 68 forks source link

Test Data Class (TCDB, TCEB, TCXB) does not identify powers of 2 as normal. #123

Closed srorso closed 8 years ago

srorso commented 8 years ago

The instructions TCDB, TCEB, TCXB, do not identify powers of 2 and selected other values as Normal floating point numbers, and identifies near-maximum magnitude subnormal numbers as normals. The issue exists for all precisions.

Hyperion ieee.c tests the first bit of the stored fraction. If 1, it reports normal, otherwise subnormal:

static INLINE U32 float32_class( float32 op )
{
    int neg =
       (  op & 0x80000000) ? 1 : 0;
    if (float32_is_signaling_nan( op )) return float_class_signaling_nan >> neg;
    if (float32_is_nan( op ))           return float_class_quiet_nan     >> neg;
    if (!(op & 0x7FFFFFFF))             return float_class_zero          >> neg;
    if ( (op & 0x7FFFFFFF)
            == 0x7F800000)              return float_class_infinity      >> neg;
    if (  op & 0x00400000)              return float_class_normal        >> neg;
                                        return float_class_subnormal     >> neg;
}

The number 2, 2^1, is represented in short BFP as 0x40000000 (biased exponent 128, fraction 0). The most significant bit of the significand,, a 1, is implied and not stored. Because the first bit of the stored fraction is zero, Hyperion identifies it as subnormal. (Any power of two will have a zero stored fraction; only one binary digit is needed to represent a power of two. The exponent tells us which power of two is stored.

A BFP short maximum magnitude positive subnormal is 0x007FFFFF (biased exponent zero, fraction non-zero (it's 1.1754942E-38). Because the first bit of the stored fraction is 1, Hyperion identifies it as normal. Positive subnormals between 0x00400000 and 0x007FFFFF inclusive will be identified as normal, as will their negative counterparts.

The z/Arch POP SA22-7832-10 Figure 16, Classes of BFP Data, on page 19-4 (p.1326) says that a BFP subnormal has a biased exponent of zero and non-zero stored fraction.

Spinhawk uses a Softfloat 2b call to identify normal versus subnormal:

flag float32_is_subnormal( float32 a )
{

    return ( ( ( a>>23 ) & 0xFF ) == 0 )
        && ( a & 0x007FFFFF );

}

The code above matches the description of a subnormal contained in the z/Arch POP -10.

A handy BFP 32-bit converter may be found here.

srorso commented 8 years ago

Note: Other normal values in short BFP will also be identified by Hyperion as subnormal, for example 9 (0x41100000), but the powers of two provide the clearest example.

Fish-Git commented 8 years ago

Spinhawk uses a Softfloat 2b call to identify normal versus subnormal:

Once again this is not a Softfloat 2b function! (It's not even in 3a!)

It's a function that either Roger wrote himself or else acquired from Dr. Hauser himself or elsewhere.

I apologize for picking nits about this, but when you say Spinhawk "uses a Softfloat 2b call" you make it sound like Hyperion, for unknown reasons, purposely did not. This is not true. If such a function had existed I'm sure I would have used it. But given that such a function did not exist at that time I couldn't. You're hurting my pride.   :)

Yes, I could have written my own just as Roger presumably did, but at the time I didn't know any better. I did what I thought was the right thing.So sue me. I'm human. My mind was spinning. Floating point does not come easy to me and I did the best I could since no one else was willing to do it.

Your point still stands however. What you've pointed out is definitely a bug that needs fixed! Well done! Good catch! I wish you had been around 10+ years ago. I'd have let you implement Softfloat in Hercules. Based on what I've seen so far I'm sure you would have done a much better job   :)

srorso commented 8 years ago

Hi Fish:

This may seem a bit OT. Please bear with me.

I apologize for picking nits about this,..

No apology needed. You are providing--twice in this instance I am sorry to say--information I really need and find helpful. These are important details, and I am grateful to have them pointed out.

...you make it sound like Hyperion, for unknown reasons, purposely did not

Not my intention, and I apologize for language that makes that interpretation reasonable.

I wish you had been around 10+ years ago. ... Based on what I've seen so far I'm sure you would have done a much better job

Not sure about that. I built test cases for 78 instructions; 76 are great (97%). You haven't left much upside opportunity. And it took someone building test cases to find this issue...no one in the field found it. Your work is worthy of admiration. It has mine. Besides, I was working ten years ago. My learning curve on this approaches vertical today; no way I could have done this back when you did.

I post this level of detail not to swing a brickbat, but so that others may see what I'm thinking and fix it before I invest in writing code. As you have...and I hope you will continue. Many thanks!

Best Regards, Steve Orso

srorso commented 8 years ago

Addressed by pull request #127