On 3/27/20 6:07 PM, LIU Zhiwei wrote:
On 2020/3/28 8:32, Richard Henderson wrote:
On 3/18/20 8:46 PM, LIU Zhiwei wrote:
+static inline int32_t asub32(CPURISCVState *env, int vxrm, int32_t a, int32_t
b)
+{
+ int64_t res = (int64_t)a - b;
+ uint8_t round = get_round(vxrm, res, 1);
+
+ return (res >> 1) + round;
+}
+
I find a corner case here. As the spec said in Section 13.2
"There can be no overflow in the result".
If the a is 0x7fffffff, b is 0x80000000, and the round mode is round to
up(rnu),
then the result is (0x7fffffff - 0x80000000 + 1) >> 1, equals 0x80000000,
according the v0.7.1
That's why we used int64_t as the intermediate type:
0x000000007fffffff - 0xffffffff80000000 + 1
= 0x000000007fffffff + 0x0000000080000000 + 1
= 0x00000000ffffffff + 1
= 0x0000000100000000
Shift that right by 1 and you do indeed get 0x80000000.
There's no saturation involved.
The minuend 0x7fffffff is INT32_MAX, and the subtrahend 0x80000000 is INT32_MIN.
The difference between the minuend and the subtrahend should be a positive
number. But the result here is 0x80000000.
So it is overflow. However, according to the spec, it should not overflow.
Unless I'm missing something, the spec is wrong about "there can be no
overflow", the above being a counter-example.
Do you have hardware to compare against? Perhaps it is in fact "overflow is
ignored", as the 0.8 spec says for vasubu?