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.hs61
1 files changed, 29 insertions, 32 deletions
diff --git a/lib/Language/Elna/RiscV/CodeGenerator.hs b/lib/Language/Elna/RiscV/CodeGenerator.hs
index a1dcdbe..fffbd39 100644
--- a/lib/Language/Elna/RiscV/CodeGenerator.hs
+++ b/lib/Language/Elna/RiscV/CodeGenerator.hs
@@ -276,25 +276,14 @@ quadruple _ (ArrayAssignQuadruple assigneeOperand indexOperand store)
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)
+ $ RiscV.S (fromIntegral $ offset + indexOffset * 4) 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
+ let storeInstruction = Instruction
$ RiscV.BaseInstruction RiscV.Store
$ RiscV.S (fromIntegral offset) RiscV.SW immediateRegister register
- statements = Vector.fromList
- [ baseRegisterInstruction
- , registerWithOffset
- , storeInstruction
- ]
- in (register, indexStatements <> statements)
+ statements = calculateIndexOffset indexOffset
+ in (register, Vector.snoc statements storeInstruction)
quadruple _ (ArrayQuadruple assigneeVariable indexOperand store) =
let (operandRegister1, statements1) = loadWithOffset assigneeVariable indexOperand
(storeRegister, storeStatements) = storeToStore store
@@ -308,25 +297,33 @@ quadruple _ (ArrayQuadruple assigneeVariable indexOperand store) =
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)
+ $ RiscV.I register RiscV.LW RiscV.S0 (fromIntegral $ offset + indexOffset * 4)
+ 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
+ let loadInstruction = Instruction
$ RiscV.BaseInstruction RiscV.Load
$ RiscV.I register RiscV.SW immediateRegister (fromIntegral offset)
- statements = Vector.fromList
- [ baseRegisterInstruction
- , registerWithOffset
- , loadInstruction
- ]
- in (register, indexStatements <> statements)
+ statements = calculateIndexOffset indexOffset
+ in (register, Vector.snoc statements loadInstruction)
+
+calculateIndexOffset :: RiscVStore -> Vector Statement
+calculateIndexOffset indexOffset =
+ let (indexRegister, indexStatements) = loadFromStore indexOffset
+ baseRegisterInstruction = Instruction
+ $ RiscV.BaseInstruction RiscV.OpImm
+ $ RiscV.I immediateRegister RiscV.ADDI RiscV.Zero 4
+ indexRelativeOffset = Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R immediateRegister RiscV.MUL immediateRegister indexRegister (RiscV.Funct7 0b0000001)
+ registerWithOffset = Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R immediateRegister RiscV.ADD immediateRegister RiscV.S0 (RiscV.Funct7 0b0000000)
+ statements = Vector.fromList
+ [ baseRegisterInstruction
+ , indexRelativeOffset
+ , registerWithOffset
+ ]
+ in indexStatements <> statements
unconditionalJal :: Label -> Statement
unconditionalJal (Label goToLabel) = Instruction