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. For int64_t we computed signed overflow to do the same thing. r~