summaryrefslogtreecommitdiff
path: root/lib/Language/Elna/RiscV/CodeGenerator.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Language/Elna/RiscV/CodeGenerator.hs')
-rw-r--r--lib/Language/Elna/RiscV/CodeGenerator.hs32
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/Language/Elna/RiscV/CodeGenerator.hs b/lib/Language/Elna/RiscV/CodeGenerator.hs
index 6e7a8cd..a1dcdbe 100644
--- a/lib/Language/Elna/RiscV/CodeGenerator.hs
+++ b/lib/Language/Elna/RiscV/CodeGenerator.hs
@@ -295,6 +295,38 @@ quadruple _ (ArrayAssignQuadruple assigneeOperand indexOperand store)
, storeInstruction
]
in (register, indexStatements <> statements)
+quadruple _ (ArrayQuadruple assigneeVariable indexOperand store) =
+ let (operandRegister1, statements1) = loadWithOffset assigneeVariable indexOperand
+ (storeRegister, storeStatements) = storeToStore store
+ instruction = Instruction
+ $ RiscV.BaseInstruction RiscV.OpImm
+ $ RiscV.I storeRegister RiscV.ADDI operandRegister1 0
+ in pure $ statements1 <> Vector.cons instruction storeStatements
+ where
+ loadWithOffset :: RiscVStore -> Operand RiscVStore -> (RiscV.XRegister, Vector Statement)
+ loadWithOffset (RegisterStore register) _ = (register, mempty)
+ loadWithOffset (StackStore offset register) (IntOperand indexOffset) =
+ let loadInstruction = Instruction
+ $ RiscV.BaseInstruction RiscV.Load
+ $ RiscV.I register RiscV.LW RiscV.S0 (fromIntegral $ offset + indexOffset)
+ in (register, Vector.singleton loadInstruction)
+ loadWithOffset (StackStore offset register) (VariableOperand indexOffset) =
+ let baseRegisterInstruction = Instruction
+ $ RiscV.BaseInstruction RiscV.OpImm
+ $ RiscV.I immediateRegister RiscV.ADDI RiscV.S0 0
+ (indexRegister, indexStatements) = loadFromStore indexOffset
+ registerWithOffset = Instruction
+ $ RiscV.BaseInstruction RiscV.OpImm
+ $ RiscV.I immediateRegister RiscV.ADDI indexRegister 0
+ loadInstruction = Instruction
+ $ RiscV.BaseInstruction RiscV.Load
+ $ RiscV.I register RiscV.SW immediateRegister (fromIntegral offset)
+ statements = Vector.fromList
+ [ baseRegisterInstruction
+ , registerWithOffset
+ , loadInstruction
+ ]
+ in (register, indexStatements <> statements)
unconditionalJal :: Label -> Statement
unconditionalJal (Label goToLabel) = Instruction