Implement division

This commit is contained in:
Eugen Wissner 2024-10-06 18:07:57 +02:00
parent 35742aa525
commit 9dbc441042
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
15 changed files with 104 additions and 27 deletions

6
TODO
View File

@ -17,8 +17,9 @@
# Register allocation
- Temporary variables always use the same register, t0. Allocate registers for
temporaries.
- Each temporary variales gets a tn register where n is the variable index. If
there more variables the allocation will fail with out of bounds runtime
error. Implement spill over.
# Prarsing and abstract syntax tree
@ -27,3 +28,4 @@
# Other
- Type analysis.
- Generate call a to _divide_by_zero_error on RiscV.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ()

View File

@ -80,7 +80,7 @@ operatorTable =
]
factorOperator =
[ binary "*" ProductExpression
-- , binary "/" DivisionExpression
, binary "/" DivisionExpression
]
termOperator =
[ binary "+" SumExpression

View File

@ -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

View File

@ -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 =

View File

@ -0,0 +1 @@
38

View File

@ -0,0 +1 @@
2

View File

@ -0,0 +1,3 @@
proc main() {
printi(2 * 3 + 4 * 8);
}

View File

@ -0,0 +1,3 @@
proc main() {
printi(4 / (2 - 2));
}

View File

@ -0,0 +1,3 @@
proc main() {
printi(4 / 2);
}

View File

@ -7,6 +7,9 @@
.global exit
.type exit, @function
.global _divide_by_zero_error
.type _divide_by_zero_error, @function
.global _start
.type _start, @function
@ -51,7 +54,7 @@ printi:
addi a0, zero, 1
addi a1, a1, 1
sub a2, s0, a1
addi a7, zero, 64
addi a7, zero, 64 # write
ecall
lw s0, 0(sp)
@ -74,7 +77,7 @@ printc:
addi a0, zero, 1
addi a1, s0, -2
addi a2, zero, 2
addi a7, zero, 64
addi a7, zero, 64 # write
ecall
lw s0, 0(sp)
@ -84,10 +87,19 @@ printc:
exit:
addi a0, zero, 0
addi a7, zero, 93
addi a7, zero, 93 # exit
ecall
# ret
_divide_by_zero_error:
addi a7, zero, 172 # getpid
ecall
addi a1, zero, 8 # SIGFPE
addi a7, zero, 129 # kill
ecall
ret
_start:
call main
call exit