Add array assignment to the IR
This commit is contained in:
parent
147967c04b
commit
4efda21007
6
TODO
6
TODO
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user