Support varying table sizes in the fast math code

Our code is currently running pretty tight on memory on the K22 (used on
fet12v2). Our encoder there also doesn't as many counts as the ones on
the pistol grip. Therefore, with a bit of cleverness and templates, we
can free up some RAM to have enough breathing room to split up the heap
and stack better.

Change-Id: Ibea73887b5570326ec1338b296f71ecab3d4ba7a
diff --git a/motors/math.cc b/motors/math.cc
index 8441e97..3f505bc 100644
--- a/motors/math.cc
+++ b/motors/math.cc
@@ -6,31 +6,31 @@
 namespace motors {
 namespace math_internal {
 
-float sin_int_table[SinCosTableSize()];
-float cos_int_table[SinCosTableSize()];
-float sin_float_table[SinCosTableSize() + 1];
-float cos_float_table[SinCosTableSize() + 1];
+float sin_float_table[SinCosFloatTableSize() + 1];
+float cos_float_table[SinCosFloatTableSize() + 1];
+
+::std::array<GenericInitializer *, 10> global_initializers{};
 
 }  // namespace math_internal
 
-using math_internal::SinCosTableSize;
+using math_internal::SinCosFloatTableSize;
 
 __attribute__((cold)) void MathInit() {
-  for (uint32_t i = 0; i < SinCosTableSize(); ++i) {
-    const double int_theta =
-        ((static_cast<double>(i) + 0.5) / SinCosTableSize()) * 2.0 * M_PI;
-    math_internal::sin_int_table[i] = sin(int_theta);
-    math_internal::cos_int_table[i] = cos(int_theta);
-  }
-  for (uint32_t i = 0; i < SinCosTableSize() + 1; ++i) {
+  for (uint32_t i = 0; i < SinCosFloatTableSize() + 1; ++i) {
     const double float_theta =
         (static_cast<int32_t>(i) -
-         static_cast<int32_t>(SinCosTableSize() / 2)) *
+         static_cast<int32_t>(SinCosFloatTableSize() / 2)) *
         static_cast<double>(math_internal::FloatMaxMagnitude()) /
-        static_cast<double>(SinCosTableSize() / 2);
+        static_cast<double>(SinCosFloatTableSize() / 2);
     math_internal::sin_float_table[i] = sin(float_theta);
     math_internal::cos_float_table[i] = cos(float_theta);
   }
+  for (math_internal::GenericInitializer *initializer :
+       math_internal::global_initializers) {
+    if (initializer != nullptr) {
+      initializer->Initialize();
+    }
+  }
 }
 
 }  // namespace motors