diff options
Diffstat (limited to 'lib/Language/Elna/RiscV/CodeGenerator.hs')
| -rw-r--r-- | lib/Language/Elna/RiscV/CodeGenerator.hs | 36 |
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 |
