Add array assignment to the IR

This commit is contained in:
Eugen Wissner 2024-12-01 11:17:14 +01:00
parent 147967c04b
commit 4efda21007
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 42 additions and 8 deletions

6
TODO
View File

@ -1,9 +1,3 @@
# Intermediate code generation
- To access named parameters inside a procedure, IR should be able to reference
them. During the generation the needed information (e.g. offsets or registers)
can be extracted from the symbol table and saved in the operands.
# ELF generation # ELF generation
- Don't ignore relocations where the symbol is not defined in the symbol table. - Don't ignore relocations where the symbol is not defined in the symbol table.

View File

@ -135,6 +135,10 @@ quadruple = \case
AssignQuadruple operand1 variable -> do AssignQuadruple operand1 variable -> do
operand1' <- operand operand1 operand1' <- operand operand1
AssignQuadruple operand1' <$> storeVariable variable AssignQuadruple operand1' <$> storeVariable variable
ArrayAssignQuadruple operand1 operand2 variable -> do
operand1' <- operand operand1
operand2' <- operand operand2
ArrayAssignQuadruple operand1' operand2' <$> storeVariable variable
operand :: Operand Variable -> Allocator r (Operand (Store r)) operand :: Operand Variable -> Allocator r (Operand (Store r))
operand (IntOperand x) = pure $ IntOperand x operand (IntOperand x) = pure $ IntOperand x

View File

@ -50,8 +50,8 @@ data Quadruple v
| DivisionQuadruple (Operand v) (Operand v) v | DivisionQuadruple (Operand v) (Operand v) v
| GoToQuadruple Label | GoToQuadruple Label
| AssignQuadruple (Operand v) v | AssignQuadruple (Operand v) v
{-| ArrayQuadruple Variable Operand Variable {-| ArrayQuadruple Variable Operand Variable -}
| ArrayAssignQuadruple Operand Operand Variable -} | ArrayAssignQuadruple (Operand v) (Operand v) v
| LessOrEqualQuadruple (Operand v) (Operand v) Label | LessOrEqualQuadruple (Operand v) (Operand v) Label
| GreaterOrEqualQuadruple (Operand v) (Operand v) Label | GreaterOrEqualQuadruple (Operand v) (Operand v) Label
| GreaterQuadruple (Operand v) (Operand v) Label | GreaterQuadruple (Operand v) (Operand v) Label

View File

@ -259,6 +259,42 @@ quadruple _ (AssignQuadruple operand1 store)
$ RiscV.BaseInstruction RiscV.OpImm $ RiscV.BaseInstruction RiscV.OpImm
$ RiscV.I storeRegister RiscV.ADDI operandRegister1 0 $ RiscV.I storeRegister RiscV.ADDI operandRegister1 0
in pure $ statements1 <> Vector.cons instruction storeStatements 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 -> Statement
unconditionalJal (Label goToLabel) = Instruction unconditionalJal (Label goToLabel) = Instruction