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.hs36
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/Language/Elna/RiscV/CodeGenerator.hs b/lib/Language/Elna/RiscV/CodeGenerator.hs
index a0ad5f9..6e7a8cd 100644
--- a/lib/Language/Elna/RiscV/CodeGenerator.hs
+++ b/lib/Language/Elna/RiscV/CodeGenerator.hs
@@ -259,6 +259,42 @@ quadruple _ (AssignQuadruple operand1 store)
$ RiscV.BaseInstruction RiscV.OpImm
$ RiscV.I storeRegister RiscV.ADDI operandRegister1 0
in pure $ statements1 <> Vector.cons instruction storeStatements
+quadruple _ (ArrayAssignQuadruple assigneeOperand indexOperand store)
+ | IntOperand immediateAssigneeOperand <- assigneeOperand =
+ let (storeRegister, storeStatements) = storeWithOffset store indexOperand
+ in pure $ lui immediateAssigneeOperand storeRegister <> storeStatements
+ | VariableOperand variableAssigneeOperand <- assigneeOperand =
+ let (assigneeOperandRegister, assigneeStatements) = loadFromStore variableAssigneeOperand
+ (storeRegister, storeStatements) = storeWithOffset store indexOperand
+ instruction = Instruction
+ $ RiscV.BaseInstruction RiscV.OpImm
+ $ RiscV.I storeRegister RiscV.ADDI assigneeOperandRegister 0
+ in pure $ assigneeStatements <> Vector.cons instruction storeStatements
+ where
+ storeWithOffset :: RiscVStore -> Operand RiscVStore -> (RiscV.XRegister, Vector Statement)
+ storeWithOffset (RegisterStore register) _ = (register, mempty)
+ storeWithOffset (StackStore offset register) (IntOperand indexOffset) =
+ let storeInstruction = Instruction
+ $ RiscV.BaseInstruction RiscV.Store
+ $ RiscV.S (fromIntegral $ offset + indexOffset) RiscV.SW RiscV.S0 register
+ in (register, Vector.singleton storeInstruction)
+ storeWithOffset (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
+ storeInstruction = Instruction
+ $ RiscV.BaseInstruction RiscV.Store
+ $ RiscV.S (fromIntegral offset) RiscV.SW immediateRegister register
+ statements = Vector.fromList
+ [ baseRegisterInstruction
+ , registerWithOffset
+ , storeInstruction
+ ]
+ in (register, indexStatements <> statements)
unconditionalJal :: Label -> Statement
unconditionalJal (Label goToLabel) = Instruction