summaryrefslogtreecommitdiff
path: root/lib/Language/Elna/RiscV/CodeGenerator.hs
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2024-10-11 16:14:01 +0200
committerEugen Wissner <belka@caraus.de>2024-10-11 16:14:01 +0200
commit0850f0a8d66af028e32a79063cdad328b70db909 (patch)
tree8c1fa49d5476e706e94a7af62ce37b12ef65e32d /lib/Language/Elna/RiscV/CodeGenerator.hs
parent87f183baad01f2b572f5f9051895b5876a56dd4c (diff)
downloadelna-0850f0a8d66af028e32a79063cdad328b70db909.tar.gz
Implement if statements with equality
Diffstat (limited to 'lib/Language/Elna/RiscV/CodeGenerator.hs')
-rw-r--r--lib/Language/Elna/RiscV/CodeGenerator.hs43
1 files changed, 42 insertions, 1 deletions
diff --git a/lib/Language/Elna/RiscV/CodeGenerator.hs b/lib/Language/Elna/RiscV/CodeGenerator.hs
index e3fac72..659e0e6 100644
--- a/lib/Language/Elna/RiscV/CodeGenerator.hs
+++ b/lib/Language/Elna/RiscV/CodeGenerator.hs
@@ -13,7 +13,7 @@ import Data.Vector (Vector)
import qualified Data.Vector as Vector
import qualified Language.Elna.Architecture.RiscV as RiscV
import Language.Elna.Backend.Allocator (MachineConfiguration(..), Store(..))
-import Language.Elna.Backend.Intermediate (Operand(..), Quadruple(..))
+import Language.Elna.Backend.Intermediate (Label(..), Operand(..), Quadruple(..))
import Language.Elna.Location (Identifier(..))
import Data.Bits (Bits(..))
import Data.Foldable (Foldable(..), foldlM)
@@ -45,6 +45,10 @@ riscVConfiguration = MachineConfiguration
]
}
+-- | Reserved register used for calculations to save an immediate temporary.
+immediateRegister :: RiscV.XRegister
+immediateRegister = RiscV.A7
+
type RiscVStore = Store RiscV.XRegister
type RiscVQuadruple = Quadruple RiscVStore
type RiscVOperand = Operand RiscVStore
@@ -243,6 +247,43 @@ quadruple (DivisionQuadruple operand1 operand2 (Store register))
$ RiscV.BaseInstruction RiscV.Op
$ RiscV.R register RiscV.DIV register operandRegister2
$ RiscV.Funct7 0b0000001
+quadruple (LabelQuadruple (Label label)) = pure $ Vector.singleton $ JumpLabel label mempty
+quadruple (GoToQuadruple label) = pure $ Vector.singleton $ unconditionalJal label
+quadruple (EqualQuadruple operand1 operand2 goToLabel)
+ | IntOperand immediateOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ if immediateOperand1 == immediateOperand2
+ then pure $ Vector.singleton $ unconditionalJal goToLabel
+ else pure Vector.empty
+ | VariableOperand variableOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 = do
+ let Store operandRegister1 = variableOperand1
+ Store operandRegister2 = variableOperand2
+ branchLabel <- createLabel
+ pure $ Vector.singleton
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch branchLabel RiscV.BEQ operandRegister1 operandRegister2
+ | VariableOperand variableOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ compareImmediateRegister variableOperand1 immediateOperand2
+ | IntOperand immediateOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ compareImmediateRegister variableOperand2 immediateOperand1
+ where
+ compareImmediateRegister variableOperand immediateOperand =
+ let statements = lui immediateOperand immediateRegister
+ Store operandRegister = variableOperand
+ Label goToLabel' = goToLabel
+ in pure $ Vector.snoc statements
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BEQ operandRegister immediateRegister
+
+unconditionalJal :: Label -> Statement
+unconditionalJal (Label goToLabel) = Instruction
+ $ RiscV.RelocatableInstruction RiscV.Jal
+ $ RiscV.RJal RiscV.Zero goToLabel
loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
loadImmediateOrRegister (IntOperand intValue) targetRegister =