summaryrefslogtreecommitdiff
path: root/lib/Language/Elna/CodeGenerator.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Language/Elna/CodeGenerator.hs')
-rw-r--r--lib/Language/Elna/CodeGenerator.hs66
1 files changed, 52 insertions, 14 deletions
diff --git a/lib/Language/Elna/CodeGenerator.hs b/lib/Language/Elna/CodeGenerator.hs
index 7df93d5..a561cb8 100644
--- a/lib/Language/Elna/CodeGenerator.hs
+++ b/lib/Language/Elna/CodeGenerator.hs
@@ -67,20 +67,58 @@ quadruple StopQuadruple = Vector.fromList
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP 4)
, Instruction (RiscV.BaseInstruction RiscV.Jalr $ RiscV.I RiscV.RA RiscV.JALR RiscV.Zero 0)
]
-quadruple (AddQuadruple operand1 operand2 (Store register)) =
- let (operandRegister1, statements1) = loadImmediateOrRegister operand1 RiscV.A0
- (operandRegister2, statements2) = loadImmediateOrRegister operand2 RiscV.A1
- in Vector.snoc (statements1 <> statements2)
- $ Instruction
- $ RiscV.BaseInstruction RiscV.Op
- $ RiscV.R register RiscV.ADD operandRegister1 operandRegister2 (RiscV.Funct7 0b0000000)
-quadruple (SubtractionQuadruple operand1 operand2 (Store register)) =
- let (operandRegister1, statements1) = loadImmediateOrRegister operand1 RiscV.A0
- (operandRegister2, statements2) = loadImmediateOrRegister operand2 RiscV.A1
- in Vector.snoc (statements1 <> statements2)
- $ Instruction
- $ RiscV.BaseInstruction RiscV.Op
- $ RiscV.R register RiscV.SUB operandRegister1 operandRegister2 (RiscV.Funct7 0b0100000)
+quadruple (AddQuadruple operand1 operand2 (Store register))
+ | IntOperand immediateOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ lui (immediateOperand1 + immediateOperand2) register
+ | VariableOperand variableOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let Store operandRegister1 = variableOperand1
+ Store operandRegister2 = variableOperand2
+ in pure $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.ADD operandRegister1 operandRegister2 (RiscV.Funct7 0b0000000)
+ | VariableOperand variableOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ addImmediateRegister variableOperand1 immediateOperand2
+ | IntOperand immediateOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ addImmediateRegister variableOperand2 immediateOperand1
+ where
+ addImmediateRegister variableOperand immediateOperand =
+ let statements = lui immediateOperand register
+ Store operandRegister = variableOperand
+ in Vector.snoc statements
+ $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.ADD register operandRegister (RiscV.Funct7 0b0000000)
+quadruple (SubtractionQuadruple operand1 operand2 (Store register))
+ | IntOperand immediateOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ lui (immediateOperand1 - immediateOperand2) register
+ | VariableOperand variableOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let Store operandRegister1 = variableOperand1
+ Store operandRegister2 = variableOperand2
+ in pure $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.SUB operandRegister1 operandRegister2 (RiscV.Funct7 0b0100000)
+ | IntOperand immediateOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let statements1 = lui immediateOperand1 register
+ Store operandRegister2 = variableOperand2
+ in Vector.snoc statements1
+ $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.SUB register operandRegister2 (RiscV.Funct7 0b0100000)
+ | VariableOperand variableOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ let statements2 = lui (negate immediateOperand2) register
+ Store operandRegister1 = variableOperand1
+ in Vector.snoc statements2
+ $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.ADD register operandRegister1 (RiscV.Funct7 0b0000000)
loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
loadImmediateOrRegister (IntOperand intValue) targetRegister =