From 0850f0a8d66af028e32a79063cdad328b70db909 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 11 Oct 2024 16:14:01 +0200 Subject: Implement if statements with equality --- lib/Language/Elna/RiscV/CodeGenerator.hs | 43 +++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'lib/Language/Elna/RiscV/CodeGenerator.hs') 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 = -- cgit v1.2.3