summaryrefslogtreecommitdiff
path: root/lib/Language/Elna/RiscV/CodeGenerator.hs
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2024-10-13 12:59:47 +0200
committerEugen Wissner <belka@caraus.de>2024-10-13 12:59:47 +0200
commit582040e5d3f6a5fb5b9046964b6823891d2802dd (patch)
tree522ecf75521f03c5dbd33921cc716fd5130da0b3 /lib/Language/Elna/RiscV/CodeGenerator.hs
parent0850f0a8d66af028e32a79063cdad328b70db909 (diff)
downloadelna-582040e5d3f6a5fb5b9046964b6823891d2802dd.tar.gz
Implement comparison operators
Diffstat (limited to 'lib/Language/Elna/RiscV/CodeGenerator.hs')
-rw-r--r--lib/Language/Elna/RiscV/CodeGenerator.hs166
1 files changed, 164 insertions, 2 deletions
diff --git a/lib/Language/Elna/RiscV/CodeGenerator.hs b/lib/Language/Elna/RiscV/CodeGenerator.hs
index 659e0e6..c364ae6 100644
--- a/lib/Language/Elna/RiscV/CodeGenerator.hs
+++ b/lib/Language/Elna/RiscV/CodeGenerator.hs
@@ -259,11 +259,11 @@ quadruple (EqualQuadruple operand1 operand2 goToLabel)
, VariableOperand variableOperand2 <- operand2 = do
let Store operandRegister1 = variableOperand1
Store operandRegister2 = variableOperand2
- branchLabel <- createLabel
+ Label goToLabel' = goToLabel
pure $ Vector.singleton
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
- $ RiscV.RBranch branchLabel RiscV.BEQ operandRegister1 operandRegister2
+ $ RiscV.RBranch goToLabel' RiscV.BEQ operandRegister1 operandRegister2
| VariableOperand variableOperand1 <- operand1
, IntOperand immediateOperand2 <- operand2 =
compareImmediateRegister variableOperand1 immediateOperand2
@@ -279,6 +279,168 @@ quadruple (EqualQuadruple operand1 operand2 goToLabel)
$ Instruction
$ RiscV.RelocatableInstruction RiscV.Branch
$ RiscV.RBranch goToLabel' RiscV.BEQ operandRegister immediateRegister
+quadruple (NonEqualQuadruple 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
+ Label goToLabel' = goToLabel
+ pure $ Vector.singleton
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BNE 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.BNE operandRegister immediateRegister
+quadruple (LessQuadruple 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
+ Label goToLabel' = goToLabel
+ pure $ Vector.singleton
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BLT operandRegister1 operandRegister2
+ | VariableOperand variableOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ let statements2 = lui immediateOperand2 immediateRegister
+ Store operandRegister1 = variableOperand1
+ Label goToLabel' = goToLabel
+ in pure $ Vector.snoc statements2
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BLT operandRegister1 immediateRegister
+ | IntOperand immediateOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let statements1 = lui immediateOperand1 immediateRegister
+ Store operandRegister2 = variableOperand2
+ Label goToLabel' = goToLabel
+ in pure $ Vector.snoc statements1
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BLT immediateRegister operandRegister2
+quadruple (GreaterQuadruple 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
+ Label goToLabel' = goToLabel
+ pure $ Vector.singleton
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BLT operandRegister2 operandRegister1
+ | VariableOperand variableOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ let statements2 = lui immediateOperand2 immediateRegister
+ Store operandRegister1 = variableOperand1
+ Label goToLabel' = goToLabel
+ in pure $ Vector.snoc statements2
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BLT immediateRegister operandRegister1
+ | IntOperand immediateOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let statements1 = lui immediateOperand1 immediateRegister
+ Store operandRegister2 = variableOperand2
+ Label goToLabel' = goToLabel
+ in pure $ Vector.snoc statements1
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BLT operandRegister2 immediateRegister
+quadruple (LessOrEqualQuadruple 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
+ Label goToLabel' = goToLabel
+ pure $ Vector.singleton
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BGE operandRegister2 operandRegister1
+ | VariableOperand variableOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ let statements2 = lui immediateOperand2 immediateRegister
+ Store operandRegister1 = variableOperand1
+ Label goToLabel' = goToLabel
+ in pure $ Vector.snoc statements2
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BGE immediateRegister operandRegister1
+ | IntOperand immediateOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let statements1 = lui immediateOperand1 immediateRegister
+ Store operandRegister2 = variableOperand2
+ Label goToLabel' = goToLabel
+ in pure $ Vector.snoc statements1
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BGE operandRegister2 immediateRegister
+quadruple (GreaterOrEqualQuadruple 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
+ Label goToLabel' = goToLabel
+ pure $ Vector.singleton
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BGE operandRegister1 operandRegister2
+ | VariableOperand variableOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ let statements2 = lui immediateOperand2 immediateRegister
+ Store operandRegister1 = variableOperand1
+ Label goToLabel' = goToLabel
+ in pure $ Vector.snoc statements2
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BGE operandRegister1 immediateRegister
+ | IntOperand immediateOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let statements1 = lui immediateOperand1 immediateRegister
+ Store operandRegister2 = variableOperand2
+ Label goToLabel' = goToLabel
+ in pure $ Vector.snoc statements1
+ $ Instruction
+ $ RiscV.RelocatableInstruction RiscV.Branch
+ $ RiscV.RBranch goToLabel' RiscV.BGE immediateRegister operandRegister2
unconditionalJal :: Label -> Statement
unconditionalJal (Label goToLabel) = Instruction