commit 30849ea740e26f1a0967e01105520c648cd0afdd
Author: David Sorber <david.sorber@gmail.com>
Date:   Tue Jul 5 10:57:20 2022 -0400

    Initial version of integer division for the fixed point type.

diff --git a/software/fixed/CMakeLists.txt b/software/fixed/CMakeLists.txt
index fba5367..d1b0c2c 100644
--- a/software/fixed/CMakeLists.txt
+++ b/software/fixed/CMakeLists.txt
@@ -16,14 +16,18 @@ ENDIF()
 
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 -march=native -fuse-ld=gold -flto")
 
-ADD_EXECUTABLE(fixed_util ${CMAKE_CURRENT_SOURCE_DIR}/fixed_util.cc)
-ADD_EXECUTABLE(parse_test ${CMAKE_CURRENT_SOURCE_DIR}/parse_test.cc)
+SET(sources
+   ${CMAKE_CURRENT_SOURCE_DIR}/int128.cc
+)
+   
+ADD_EXECUTABLE(fixed_util ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/fixed_util.cc)
+ADD_EXECUTABLE(parse_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/parse_test.cc)
 
 # Test executables
-ADD_EXECUTABLE(fixed_test ${CMAKE_CURRENT_SOURCE_DIR}/fixed_test.cc)
+ADD_EXECUTABLE(fixed_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/fixed_test.cc)
 TARGET_LINK_LIBRARIES(fixed_test ${EXTERNAL_LIBS})
 
-ADD_EXECUTABLE(int128_test ${CMAKE_CURRENT_SOURCE_DIR}/int128_test.cc)
+ADD_EXECUTABLE(int128_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/int128_test.cc)
 TARGET_LINK_LIBRARIES(int128_test ${EXTERNAL_LIBS})
 
 ADD_TEST(NAME test_int128t COMMAND int128_test)
diff --git a/software/fixed/fixed.h b/software/fixed/fixed.h
index fec118a..037c9aa 100644
--- a/software/fixed/fixed.h
+++ b/software/fixed/fixed.h
@@ -47,7 +47,8 @@
 #endif
 
 #if SUPPORT_128_INTS
-#include "Utilities/int128.h"
+#include "int128.h"
+//~ #include "Utilities/int128.h"
 #endif
 
 
@@ -462,7 +463,12 @@ public:
     friend constexpr inline bool operator>=(
         const fixed<I, F, STI, STF>& x, const fixed<I, F, STI, STF>& y) noexcept;
 
-    // Divide by unsigned int
+    // Multiply by integer
+    template<typename I, typename F, typename STI, typename STF>
+    friend constexpr inline fixed<I, F, STI, STF> operator*(
+        const fixed<I, F, STI, STF>& x, const int64_t& y);
+
+    // Divide by integer
     template<typename I, typename F, typename STI, typename STF>
     friend constexpr inline fixed<I, F, STI, STF> operator/(
         const fixed<I, F, STI, STF>& x, const int64_t& y);
@@ -895,7 +901,59 @@ template<typename I, typename F, typename STI, typename STF>
 constexpr inline fixed<I, F, STI, STF> operator/(
     const fixed<I, F, STI, STF>& x, const fixed<I, F, STI, STF>& y) noexcept = delete;
 
-// Division by unsigned int
+// Multiplication by integer
+template<typename I, typename F, typename STI, typename STF>
+constexpr inline fixed<I, F, STI, STF> operator*(
+     const fixed<I, F, STI, STF>& x, const int64_t& y)
+{
+    fixed<I, F, STI, STF> newVal;
+    //~ bool negativeDivisorFlag = (y < 0);
+    //~ bool negativeDividendFlag = (x.m_integer < 0) || 
+                                //~ (x.m_integer == fixed<I, F, STI, STF>::NEGATIVE_ZERO);
+    //~ bool negativeZeroFlag = false;
+    //~ I integerX = x.m_integer;
+    //~ if (__unlikely((integerX == fixed<I, F, STI, STF>::NEGATIVE_ZERO)))
+    //~ {
+        //~ integerX = 0;
+        //~ negativeZeroFlag = true;
+    //~ }
+    
+    // Straight multiply for integer portion
+    newVal.m_integer = x.m_integer * y;
+    
+    std::cout << "INTEGER: " << newVal.m_integer << std::endl;
+    
+    std::cout << "Frac digits: " << fixed<I, F, STI, STF>::fractional_decimal_digits << std::endl;
+    std::cout << "Half Frac digits: " << (fixed<I, F, STI, STF>::fractional_decimal_digits / 2) << std::endl;
+    
+    uint32_t index = (fixed<I, F, STI, STF>::fractional_decimal_digits / 2);
+    
+#if SUPPORT_128_INTS
+    uint128_t scaler = fixed<I, F, STI, STF>::SCALE_VALUES[index];
+#else
+    uint64_t scaler = fixed<I, F, STI, STF>::SCALE_VALUES[index];
+#endif
+    
+    // Handle upper and lower portions of fractional value separarely so that
+    // the integer carry can be handled
+    std::cout << "[1] FRAC upper: " << (x.m_fractional / scaler) << std::endl;
+    F fracUpper = (x.m_fractional / scaler) * y;
+    std::cout << "[2] FRAC upper: " << fracUpper << std::endl;
+    newVal.m_fractional = (fracUpper % (scaler * 10)) * scaler;
+    std::cout << "NEW FRAC upper: " << newVal.m_fractional << std::endl;
+    
+    F carry = (fracUpper / (scaler * 10));
+    std::cout << "Carry: " << carry << std::endl;
+    newVal.m_integer += carry;
+    
+    F fracLower = (x.m_fractional % scaler) * y;
+    std::cout << "FRAC lower: " << fracLower << std::endl;
+    newVal.m_fractional += fracLower;
+    
+    return newVal;
+}
+
+// Division by integer
 template<typename I, typename F, typename STI, typename STF>
 constexpr inline fixed<I, F, STI, STF> operator/(
      const fixed<I, F, STI, STF>& x, const int64_t& y)
diff --git a/software/fixed/fixed_util.cc b/software/fixed/fixed_util.cc
index 17a764e..9a84910 100644
--- a/software/fixed/fixed_util.cc
+++ b/software/fixed/fixed_util.cc
@@ -12,7 +12,18 @@
 int main(int argc, char** argv)
 {
     std::cout << "Fixed Type Test Util\n" << std::endl;
+    
+    fixed_64_64 val;
+    fixed_64_64 val2;
+    val.parse("0.314159263538979");
+    std::cout << "[1] Val: " << val << std::endl;
+    val2 = val * 10;
+    std::cout << "[2] Val: " << val2 << std::endl;
+    
+    val2 = val * 86;
+    std::cout << "[3] Val: " << val2 << std::endl;
 
+#if 0
     //-------------------------------------------------------------------------
     fixed_64_64 foobar;
     std::cout << "Type size: " << sizeof(fixed_64_64) << std::endl;
@@ -115,6 +126,7 @@ int main(int argc, char** argv)
     uint128_t u128Val = strtoull_128(strVal, nullptr, 0);
     std::cout << "String value: " << strVal << std::endl;
     std::cout << "Parsed value: " << u128Val << std::endl;
+#endif
     
     return 0;
 }
