summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2024-10-06 18:07:57 +0200
committerEugen Wissner <belka@caraus.de>2024-10-06 18:09:08 +0200
commit699cc8684b1571d2501bac2c8bdf461127a420a1 (patch)
tree9caecb24007eda52a074f348bbd613da033a2069 /lib
parent35742aa52587400950cf25170c2247f98f498d4d (diff)
downloadelna-699cc8684b1571d2501bac2c8bdf461127a420a1.tar.gz
Implement division
Diffstat (limited to 'lib')
-rw-r--r--lib/Language/Elna/Backend/Allocator.hs35
-rw-r--r--lib/Language/Elna/Backend/Intermediate.hs2
-rw-r--r--lib/Language/Elna/Frontend/AST.hs8
-rw-r--r--lib/Language/Elna/Frontend/NameAnalysis.hs4
-rw-r--r--lib/Language/Elna/Frontend/Parser.hs2
-rw-r--r--lib/Language/Elna/Glue.hs6
-rw-r--r--lib/Language/Elna/RiscV/CodeGenerator.hs39
7 files changed, 74 insertions, 22 deletions
diff --git a/lib/Language/Elna/Backend/Allocator.hs b/lib/Language/Elna/Backend/Allocator.hs
index 1ffc85d..701beb8 100644
--- a/lib/Language/Elna/Backend/Allocator.hs
+++ b/lib/Language/Elna/Backend/Allocator.hs
@@ -12,7 +12,7 @@ import Language.Elna.Location (Identifier(..))
newtype Store r = Store r
newtype MachineConfiguration r = MachineConfiguration
- { temporaryRegister :: r
+ { temporaryRegisters :: [r]
}
allocate
@@ -30,14 +30,29 @@ allocate MachineConfiguration{..} = fmap function
quadruple (ParameterQuadruple operand1) =
ParameterQuadruple (operand operand1)
quadruple (CallQuadruple name count) = CallQuadruple name count
- quadruple (AddQuadruple operand1 operand2 _) =
- AddQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
- quadruple (SubtractionQuadruple operand1 operand2 _) =
- SubtractionQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
- quadruple (NegationQuadruple operand1 _) =
- NegationQuadruple (operand operand1) (Store temporaryRegister)
- quadruple (ProductQuadruple operand1 operand2 _) =
- ProductQuadruple (operand operand1) (operand operand2) (Store temporaryRegister)
+ quadruple (AddQuadruple operand1 operand2 (TempVariable index))
+ = AddQuadruple (operand operand1) (operand operand2)
+ $ Store
+ $ temporaryRegisters !! fromIntegral index
+ quadruple (SubtractionQuadruple operand1 operand2 (TempVariable index))
+ = SubtractionQuadruple (operand operand1) (operand operand2)
+ $ Store
+ $ temporaryRegisters !! fromIntegral index
+ quadruple (NegationQuadruple operand1 (TempVariable index))
+ = NegationQuadruple (operand operand1)
+ $ Store
+ $ temporaryRegisters !! fromIntegral index
+ quadruple (ProductQuadruple operand1 operand2 (TempVariable index))
+ = ProductQuadruple (operand operand1) (operand operand2)
+ $ Store
+ $ temporaryRegisters !! fromIntegral index
+ quadruple (DivisionQuadruple operand1 operand2 (TempVariable index))
+ = DivisionQuadruple (operand operand1) (operand operand2)
+ $ Store
+ $ temporaryRegisters !! fromIntegral index
operand :: Operand Variable -> Operand (Store r)
operand (IntOperand x) = IntOperand x
- operand (VariableOperand _) = VariableOperand (Store temporaryRegister)
+ operand (VariableOperand (TempVariable index))
+ = VariableOperand
+ $ Store
+ $ temporaryRegisters !! fromIntegral index
diff --git a/lib/Language/Elna/Backend/Intermediate.hs b/lib/Language/Elna/Backend/Intermediate.hs
index e7c66cf..380fba7 100644
--- a/lib/Language/Elna/Backend/Intermediate.hs
+++ b/lib/Language/Elna/Backend/Intermediate.hs
@@ -31,11 +31,11 @@ data Quadruple v
| SubtractionQuadruple (Operand v) (Operand v) v
| NegationQuadruple (Operand v) v
| ProductQuadruple (Operand v) (Operand v) v
+ | DivisionQuadruple (Operand v) (Operand v) v
{-| GoToQuadruple Label
| AssignQuadruple Operand Variable
| ArrayQuadruple Variable Operand Variable
| ArrayAssignQuadruple Operand Operand Variable
- | DivisionQuadruple Operand Operand Variable
| EqualQuadruple Operand Operand Label
| NonEqualQuadruple Operand Operand Label
| LessQuadruple Operand Operand Label
diff --git a/lib/Language/Elna/Frontend/AST.hs b/lib/Language/Elna/Frontend/AST.hs
index 4c1c20b..b9ed539 100644
--- a/lib/Language/Elna/Frontend/AST.hs
+++ b/lib/Language/Elna/Frontend/AST.hs
@@ -119,8 +119,8 @@ data Expression
| SubtractionExpression Expression Expression
| NegationExpression Expression
| ProductExpression Expression Expression
-{- | VariableExpression VariableAccess
- | DivisionExpression Expression Expression -}
+ | DivisionExpression Expression Expression
+ -- | VariableExpression VariableAccess
deriving Eq
instance Show Expression
@@ -130,8 +130,8 @@ instance Show Expression
show (SubtractionExpression lhs rhs) = concat [show lhs, " - ", show rhs]
show (NegationExpression negation) = '-' : show negation
show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs]
- {- show (VariableExpression variable) = show variable
- show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs] -}
+ show (DivisionExpression lhs rhs) = concat [show lhs, " / ", show rhs]
+ -- show (VariableExpression variable) = show variable
{-
data VariableAccess
= VariableAccess Identifier
diff --git a/lib/Language/Elna/Frontend/NameAnalysis.hs b/lib/Language/Elna/Frontend/NameAnalysis.hs
index dc39826..18ae6dd 100644
--- a/lib/Language/Elna/Frontend/NameAnalysis.hs
+++ b/lib/Language/Elna/Frontend/NameAnalysis.hs
@@ -147,11 +147,11 @@ expression globalTable (AST.NegationExpression negation) =
expression globalTable (AST.ProductExpression lhs rhs)
= expression globalTable lhs
>> expression globalTable rhs
-{- expression globalTable (AST.VariableExpression variableExpression) =
- variableAccess globalTable variableExpression
expression globalTable (AST.DivisionExpression lhs rhs)
= expression globalTable lhs
>> expression globalTable rhs
+{- expression globalTable (AST.VariableExpression variableExpression) =
+ variableAccess globalTable variableExpression
-}
statement :: SymbolTable -> AST.Statement -> NameAnalysis ()
statement _ AST.EmptyStatement = pure ()
diff --git a/lib/Language/Elna/Frontend/Parser.hs b/lib/Language/Elna/Frontend/Parser.hs
index 75f359e..9d6bb60 100644
--- a/lib/Language/Elna/Frontend/Parser.hs
+++ b/lib/Language/Elna/Frontend/Parser.hs
@@ -80,7 +80,7 @@ operatorTable =
]
factorOperator =
[ binary "*" ProductExpression
- -- , binary "/" DivisionExpression
+ , binary "/" DivisionExpression
]
termOperator =
[ binary "+" SumExpression
diff --git a/lib/Language/Elna/Glue.hs b/lib/Language/Elna/Glue.hs
index 85c8401..31c31e0 100644
--- a/lib/Language/Elna/Glue.hs
+++ b/lib/Language/Elna/Glue.hs
@@ -235,6 +235,8 @@ expression localTable = \case
)
(AST.ProductExpression lhs rhs) ->
binaryExpression ProductQuadruple lhs rhs
+ (AST.DivisionExpression lhs rhs) ->
+ binaryExpression DivisionQuadruple lhs rhs
{- (AST.VariableExpression variableExpression) -> do
let variableType' = variableType variableExpression localTable
variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
@@ -247,9 +249,7 @@ expression localTable = \case
pure
( VariableOperand arrayAddress
, Vector.snoc statements arrayStatement
- )
- (AST.DivisionExpression lhs rhs) ->
- binaryExpression DivisionQuadruple lhs rhs -}
+ ) -}
where
binaryExpression f lhs rhs = do
(lhsOperand, lhsStatements) <- expression localTable lhs
diff --git a/lib/Language/Elna/RiscV/CodeGenerator.hs b/lib/Language/Elna/RiscV/CodeGenerator.hs
index 439f99c..5bc9228 100644
--- a/lib/Language/Elna/RiscV/CodeGenerator.hs
+++ b/lib/Language/Elna/RiscV/CodeGenerator.hs
@@ -29,7 +29,15 @@ data Statement
riscVConfiguration :: MachineConfiguration RiscV.XRegister
riscVConfiguration = MachineConfiguration
- { temporaryRegister = RiscV.T0
+ { temporaryRegisters =
+ [ RiscV.T0
+ , RiscV.T1
+ , RiscV.T2
+ , RiscV.T3
+ , RiscV.T4
+ , RiscV.T5
+ , RiscV.T6
+ ]
}
type RiscVStore = Store RiscV.XRegister
@@ -158,6 +166,35 @@ quadruple (ProductQuadruple operand1 operand2 (Store register))
$ RiscV.BaseInstruction RiscV.Op
$ RiscV.R register RiscV.MUL register operandRegister
$ RiscV.Funct7 0b0000001
+quadruple (DivisionQuadruple operand1 operand2 (Store register))
+ | IntOperand immediateOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ lui (quot immediateOperand1 immediateOperand2) register
+ | VariableOperand variableOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let Store operandRegister1 = variableOperand1
+ Store operandRegister2 = variableOperand2
+ in pure $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.DIV operandRegister1 operandRegister2 (RiscV.Funct7 0b0000001)
+ | VariableOperand variableOperand1 <- operand1
+ , IntOperand immediateOperand2 <- operand2 =
+ let statements2 = lui immediateOperand2 register
+ Store operandRegister1 = variableOperand1
+ in Vector.snoc statements2
+ $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.DIV operandRegister1 register
+ $ RiscV.Funct7 0b0000001
+ | IntOperand immediateOperand1 <- operand1
+ , VariableOperand variableOperand2 <- operand2 =
+ let statements1 = lui immediateOperand1 register
+ Store operandRegister2 = variableOperand2
+ in Vector.snoc statements1
+ $ Instruction
+ $ RiscV.BaseInstruction RiscV.Op
+ $ RiscV.R register RiscV.DIV register operandRegister2
+ $ RiscV.Funct7 0b0000001
loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
loadImmediateOrRegister (IntOperand intValue) targetRegister =