Browse Source

rvv: fix INT_ROUNDING compliance

* round-to-nearest-even: In the case that result[gb] = 0, the result
  should still be rounded up if result[gb-1] != 0 && result[gb-2:0] != 0
  (the usual round-to-nearest behavior outside of the tiebreaker).
* round-down: Since all uses of INT_ROUNDING() are immediately followed
  with a right shift by gb, clearing the lower bits is unnecessary.
* round-to-odd: The LSB should be OR'd only if result[gb-1:0] != 0.

Signed-off-by: Albert Ou <aou@eecs.berkeley.edu>
pull/355/head
Albert Ou 7 years ago
committed by Chih-Min Chao
parent
commit
590abe0960
  1. 24
      riscv/decode.h

24
riscv/decode.h

@ -476,31 +476,27 @@ static inline bool is_overlaped(const int astart, const int asize,
#define INT_ROUNDING(result, xrm, gb) \
if (gb > 0) { \
switch(xrm) {\
do { \
const uint64_t lsb = 1UL << (gb); \
const uint64_t lsb_half = lsb >> 1; \
switch (xrm) {\
case VRM::RNU:\
result += ((uint64_t)1 << ((gb) - 1));\
result += lsb_half; \
break;\
case VRM::RNE:\
if ((result & ((uint64_t)0x3 << ((gb) - 1))) == 0x1){\
result -= ((uint64_t)1 << ((gb) - 1));\
}else if ((result & ((uint64_t)0x3 << ((gb) - 1))) == 0x3){\
result += ((uint64_t)1 << ((gb) - 1));\
}\
if ((result & lsb_half) && ((result & (lsb_half - 1)) || (result & lsb))) \
result += lsb; \
break;\
case VRM::RDN:\
result = (result >> ((gb) - 1)) << ((gb) - 1);\
break;\
case VRM::ROD:\
result |= ((uint64_t)1ul << (gb)); \
if (result & (lsb - 1)) \
result |= lsb; \
break;\
case VRM::INVALID_RM:\
assert(true);\
} \
} else if (gb == 0 && xrm == VRM::ROD) { \
result |= 1ul; \
}
} while (0)
//
// vector: integer and masking operand access helper

Loading…
Cancel
Save