From 8ee16c9f095aaf33e51b2c1de313a16af3a0da9e Mon Sep 17 00:00:00 2001
From: Aaron Councilman <aaronjc4@illinois.edu>
Date: Mon, 30 Sep 2024 13:26:44 -0500
Subject: [PATCH] Dynamic constant remainder

---
 hercules_cg/src/sched_gen.rs | 4 +++-
 hercules_ir/src/build.rs     | 5 +++++
 hercules_ir/src/ir.rs        | 5 ++++-
 hercules_ir/src/parse.rs     | 3 ++-
 hercules_ir/src/typecheck.rs | 1 +
 5 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/hercules_cg/src/sched_gen.rs b/hercules_cg/src/sched_gen.rs
index fe08c520..586dd148 100644
--- a/hercules_cg/src/sched_gen.rs
+++ b/hercules_cg/src/sched_gen.rs
@@ -1230,7 +1230,8 @@ impl<'a> FunctionContext<'a> {
             DynamicConstant::Add(left, right)
             | DynamicConstant::Sub(left, right)
             | DynamicConstant::Mul(left, right)
-            | DynamicConstant::Div(left, right) => {
+            | DynamicConstant::Div(left, right)
+            | DynamicConstant::Rem(left, right) => {
                 let left = self.compile_dynamic_constant(left, block, partition_idx, manifest);
                 let right = self.compile_dynamic_constant(right, block, partition_idx, manifest);
                 let output_virt_reg = self.make_virt_reg(partition_idx);
@@ -1242,6 +1243,7 @@ impl<'a> FunctionContext<'a> {
                         DynamicConstant::Sub(_, _) => SBinaryOperator::Sub,
                         DynamicConstant::Mul(_, _) => SBinaryOperator::Mul,
                         DynamicConstant::Div(_, _) => SBinaryOperator::Div,
+                        DynamicConstant::Rem(_, _) => SBinaryOperator::Rem,
                         _ => panic!(),
                     },
                 });
diff --git a/hercules_ir/src/build.rs b/hercules_ir/src/build.rs
index 59b4a9f9..4202a274 100644
--- a/hercules_ir/src/build.rs
+++ b/hercules_ir/src/build.rs
@@ -419,6 +419,11 @@ impl<'a> Builder<'a> {
         self.intern_dynamic_constant(DynamicConstant::Div(x, y))
     }
 
+    pub fn create_dynamic_constant_rem(&mut self, x: DynamicConstantID,
+                                       y: DynamicConstantID) -> DynamicConstantID {
+        self.intern_dynamic_constant(DynamicConstant::Rem(x, y))
+    }
+
     pub fn create_field_index(&self, idx: usize) -> Index {
         Index::Field(idx)
     }
diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs
index 8f568282..d369138c 100644
--- a/hercules_ir/src/ir.rs
+++ b/hercules_ir/src/ir.rs
@@ -118,6 +118,7 @@ pub enum DynamicConstant {
     Sub(DynamicConstantID, DynamicConstantID),
     Mul(DynamicConstantID, DynamicConstantID),
     Div(DynamicConstantID, DynamicConstantID),
+    Rem(DynamicConstantID, DynamicConstantID),
 }
 
 /*
@@ -401,12 +402,14 @@ impl Module {
             DynamicConstant::Add(x, y)
             | DynamicConstant::Sub(x, y)
             | DynamicConstant::Mul(x, y)
-            | DynamicConstant::Div(x, y) => {
+            | DynamicConstant::Div(x, y)
+            | DynamicConstant::Rem(x, y) => {
                 match &self.dynamic_constants[dc_id.idx()] {
                     DynamicConstant::Add(_, _) => write!(w, "+")?,
                     DynamicConstant::Sub(_, _) => write!(w, "-")?,
                     DynamicConstant::Mul(_, _) => write!(w, "*")?,
                     DynamicConstant::Div(_, _) => write!(w, "/")?,
+                    DynamicConstant::Rem(_, _) => write!(w, "%")?,
                     _ => (),
                 }
                 write!(w, "(")?;
diff --git a/hercules_ir/src/parse.rs b/hercules_ir/src/parse.rs
index 3d758eb5..cb888154 100644
--- a/hercules_ir/src/parse.rs
+++ b/hercules_ir/src/parse.rs
@@ -911,7 +911,7 @@ fn parse_dynamic_constant<'a>(
         // Dynamic constant math is written using a prefix function
         nom::combinator::map(
             nom::sequence::tuple((
-                    nom::character::complete::one_of("+-*/"),
+                    nom::character::complete::one_of("+-*/%"),
                     parse_tuple2(|x| parse_dynamic_constant_id(x, context),
                                  |x| parse_dynamic_constant_id(x, context)))),
             |(op, (x, y))|
@@ -919,6 +919,7 @@ fn parse_dynamic_constant<'a>(
                            '-' => DynamicConstant::Sub(x, y),
                            '*' => DynamicConstant::Mul(x, y),
                            '/' => DynamicConstant::Div(x, y),
+                           '%' => DynamicConstant::Rem(x, y),
                            _ => panic!("Invalid parse") }
         ),
     ))(ir_text)?;
diff --git a/hercules_ir/src/typecheck.rs b/hercules_ir/src/typecheck.rs
index f9c2e07f..d2b97e53 100644
--- a/hercules_ir/src/typecheck.rs
+++ b/hercules_ir/src/typecheck.rs
@@ -185,6 +185,7 @@ fn typeflow(
             | DynamicConstant::Sub(x, y)
             | DynamicConstant::Mul(x, y)
             | DynamicConstant::Div(x, y)
+            | DynamicConstant::Rem(x, y)
                 => check_dynamic_constants(x, dynamic_constants, num_parameters)
                 && check_dynamic_constants(y, dynamic_constants, num_parameters),
         }
-- 
GitLab