Calculate stack offset from array index

This commit is contained in:
Eugen Wissner 2024-12-08 16:19:52 +01:00
parent 1c996b3c8b
commit 7fc90f1d2d
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 42 additions and 33 deletions

View File

@ -7,7 +7,6 @@ module Language.Elna.Backend.Allocator
import Data.HashMap.Strict (HashMap) import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap import qualified Data.HashMap.Strict as HashMap
import Data.Int (Int32) import Data.Int (Int32)
import Data.Word (Word32)
import Data.Vector (Vector) import Data.Vector (Vector)
import Language.Elna.Backend.Intermediate import Language.Elna.Backend.Intermediate
( ProcedureQuadruples(..) ( ProcedureQuadruples(..)

View File

@ -276,25 +276,14 @@ quadruple _ (ArrayAssignQuadruple assigneeOperand indexOperand store)
storeWithOffset (StackStore offset register) (IntOperand indexOffset) = storeWithOffset (StackStore offset register) (IntOperand indexOffset) =
let storeInstruction = Instruction let storeInstruction = Instruction
$ RiscV.BaseInstruction RiscV.Store $ RiscV.BaseInstruction RiscV.Store
$ RiscV.S (fromIntegral $ offset + indexOffset) RiscV.SW RiscV.S0 register $ RiscV.S (fromIntegral $ offset + indexOffset * 4) RiscV.SW RiscV.S0 register
in (register, Vector.singleton storeInstruction) in (register, Vector.singleton storeInstruction)
storeWithOffset (StackStore offset register) (VariableOperand indexOffset) = storeWithOffset (StackStore offset register) (VariableOperand indexOffset) =
let baseRegisterInstruction = Instruction let storeInstruction = 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.BaseInstruction RiscV.Store
$ RiscV.S (fromIntegral offset) RiscV.SW immediateRegister register $ RiscV.S (fromIntegral offset) RiscV.SW immediateRegister register
statements = Vector.fromList statements = calculateIndexOffset indexOffset
[ baseRegisterInstruction in (register, Vector.snoc statements storeInstruction)
, registerWithOffset
, storeInstruction
]
in (register, indexStatements <> statements)
quadruple _ (ArrayQuadruple assigneeVariable indexOperand store) = quadruple _ (ArrayQuadruple assigneeVariable indexOperand store) =
let (operandRegister1, statements1) = loadWithOffset assigneeVariable indexOperand let (operandRegister1, statements1) = loadWithOffset assigneeVariable indexOperand
(storeRegister, storeStatements) = storeToStore store (storeRegister, storeStatements) = storeToStore store
@ -308,25 +297,33 @@ quadruple _ (ArrayQuadruple assigneeVariable indexOperand store) =
loadWithOffset (StackStore offset register) (IntOperand indexOffset) = loadWithOffset (StackStore offset register) (IntOperand indexOffset) =
let loadInstruction = Instruction let loadInstruction = Instruction
$ RiscV.BaseInstruction RiscV.Load $ RiscV.BaseInstruction RiscV.Load
$ RiscV.I register RiscV.LW RiscV.S0 (fromIntegral $ offset + indexOffset) $ RiscV.I register RiscV.LW RiscV.S0 (fromIntegral $ offset + indexOffset * 4)
in (register, Vector.singleton loadInstruction) in (register, Vector.singleton loadInstruction)
loadWithOffset (StackStore offset register) (VariableOperand indexOffset) = loadWithOffset (StackStore offset register) (VariableOperand indexOffset) =
let baseRegisterInstruction = Instruction let loadInstruction = 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.BaseInstruction RiscV.Load
$ RiscV.I register RiscV.SW immediateRegister (fromIntegral offset) $ RiscV.I register RiscV.SW immediateRegister (fromIntegral offset)
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 statements = Vector.fromList
[ baseRegisterInstruction [ baseRegisterInstruction
, indexRelativeOffset
, registerWithOffset , registerWithOffset
, loadInstruction
] ]
in (register, indexStatements <> statements) in indexStatements <> statements
unconditionalJal :: Label -> Statement unconditionalJal :: Label -> Statement
unconditionalJal (Label goToLabel) = Instruction unconditionalJal (Label goToLabel) = Instruction

View File

@ -0,0 +1,2 @@
5
7

View File

@ -0,0 +1,11 @@
proc main() {
var a: array[2] of int;
var i: int;
i := 1;
a[0] := 5;
a[i] := 7;
printi(a[0]);
printi(a[i]);
}