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 minuendand 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.
I think a special process for (INT*_MAX - INT*_MIN) is needed.
Zhiwei
For int64_t we computed signed overflow to do the same thing.
r~