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
|
||||
|
||||
- Don't ignore relocations where the symbol is not defined in the symbol table.
|
||||
|
@ -135,6 +135,10 @@ quadruple = \case
|
||||
AssignQuadruple operand1 variable -> do
|
||||
operand1' <- operand operand1
|
||||
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 (IntOperand x) = pure $ IntOperand x
|
||||
|
@ -50,8 +50,8 @@ data Quadruple v
|
||||
| DivisionQuadruple (Operand v) (Operand v) v
|
||||
| GoToQuadruple Label
|
||||
| AssignQuadruple (Operand v) v
|
||||
{-| ArrayQuadruple Variable Operand Variable
|
||||
| ArrayAssignQuadruple Operand Operand Variable -}
|
||||
{-| ArrayQuadruple Variable Operand Variable -}
|
||||
| ArrayAssignQuadruple (Operand v) (Operand v) v
|
||||
| LessOrEqualQuadruple (Operand v) (Operand v) Label
|
||||
| GreaterOrEqualQuadruple (Operand v) (Operand v) Label
|
||||
| GreaterQuadruple (Operand v) (Operand v) Label
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user