From 1227c3681be8e6365e91e77b06dcbe58ff6c7593 Mon Sep 17 00:00:00 2001
From: Andy Knowles <andy.knowles@gmail.com>
Date: Wed, 12 Aug 2020 11:32:57 +0200
Subject: [PATCH] cxxrtl.h: Fix incorrect CarryOut in alu when Bits % 32 != 0
 && Invert == False

---
 backends/cxxrtl/cxxrtl.h | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

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<value<Bits>> {
 	std::pair<value<Bits>, bool /*CarryOut*/> alu(const value<Bits> &other) const {
 		value<Bits> 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};
 	}