From: Andy Knowles Date: Wed, 12 Aug 2020 09:32:57 +0000 (+0200) Subject: cxxrtl.h: Fix incorrect CarryOut in alu when Bits % 32 != 0 && Invert == False X-Git-Tag: working-ls180~329^2~1 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1227c3681be8e6365e91e77b06dcbe58ff6c7593;p=yosys.git cxxrtl.h: Fix incorrect CarryOut in alu when Bits % 32 != 0 && Invert == False --- diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index f0d7b9fc7..dfdb49929 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -450,12 +450,18 @@ struct value : public expr_base> { std::pair, bool /*CarryOut*/> alu(const value &other) const { value result; bool carry = CarryIn; - for (size_t n = 0; n < result.chunks; n++) { + // Handle full chunks first + for (size_t n = 0; n < result.chunks - 1; n++) { result.data[n] = data[n] + (Invert ? ~other.data[n] : other.data[n]) + carry; carry = (result.data[n] < data[n]) || (result.data[n] == data[n] && carry); } - result.data[result.chunks - 1] &= result.msb_mask; + // Handle last chunk (mask before updating carry) + constexpr size_t last = result.chunks - 1; + result.data[last] = data[last] + (Invert ? ~other.data[last] : other.data[last]) + carry; + result.data[last] &= result.msb_mask; + carry = (result.data[last] < data[last]) || + (result.data[last] == data[last] && carry); return {result, carry}; }