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 # Register allocation
- Temporary variables always use the same register, t0. Allocate registers for - Each temporary variales gets a tn register where n is the variable index. If
temporaries. there more variables the allocation will fail with out of bounds runtime
error. Implement spill over.
# Prarsing and abstract syntax tree # Prarsing and abstract syntax tree
@ -27,3 +28,4 @@
# Other # Other
- Type analysis. - 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 Store r = Store r
newtype MachineConfiguration r = MachineConfiguration newtype MachineConfiguration r = MachineConfiguration
{ temporaryRegister :: r { temporaryRegisters :: [r]
} }
allocate allocate
@ -30,14 +30,29 @@ allocate MachineConfiguration{..} = fmap function
quadruple (ParameterQuadruple operand1) = quadruple (ParameterQuadruple operand1) =
ParameterQuadruple (operand operand1) ParameterQuadruple (operand operand1)
quadruple (CallQuadruple name count) = CallQuadruple name count quadruple (CallQuadruple name count) = CallQuadruple name count
quadruple (AddQuadruple operand1 operand2 _) = quadruple (AddQuadruple operand1 operand2 (TempVariable index))
AddQuadruple (operand operand1) (operand operand2) (Store temporaryRegister) = AddQuadruple (operand operand1) (operand operand2)
quadruple (SubtractionQuadruple operand1 operand2 _) = $ Store
SubtractionQuadruple (operand operand1) (operand operand2) (Store temporaryRegister) $ temporaryRegisters !! fromIntegral index
quadruple (NegationQuadruple operand1 _) = quadruple (SubtractionQuadruple operand1 operand2 (TempVariable index))
NegationQuadruple (operand operand1) (Store temporaryRegister) = SubtractionQuadruple (operand operand1) (operand operand2)
quadruple (ProductQuadruple operand1 operand2 _) = $ Store
ProductQuadruple (operand operand1) (operand operand2) (Store temporaryRegister) $ 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 :: Operand Variable -> Operand (Store r)
operand (IntOperand x) = IntOperand x 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 | SubtractionQuadruple (Operand v) (Operand v) v
| NegationQuadruple (Operand v) v | NegationQuadruple (Operand v) v
| ProductQuadruple (Operand v) (Operand v) v | ProductQuadruple (Operand v) (Operand v) v
| DivisionQuadruple (Operand v) (Operand v) v
{-| GoToQuadruple Label {-| GoToQuadruple Label
| AssignQuadruple Operand Variable | AssignQuadruple Operand Variable
| ArrayQuadruple Variable Operand Variable | ArrayQuadruple Variable Operand Variable
| ArrayAssignQuadruple Operand Operand Variable | ArrayAssignQuadruple Operand Operand Variable
| DivisionQuadruple Operand Operand Variable
| EqualQuadruple Operand Operand Label | EqualQuadruple Operand Operand Label
| NonEqualQuadruple Operand Operand Label | NonEqualQuadruple Operand Operand Label
| LessQuadruple Operand Operand Label | LessQuadruple Operand Operand Label

View File

@ -119,8 +119,8 @@ data Expression
| SubtractionExpression Expression Expression | SubtractionExpression Expression Expression
| NegationExpression Expression | NegationExpression Expression
| ProductExpression Expression Expression | ProductExpression Expression Expression
{- | VariableExpression VariableAccess | DivisionExpression Expression Expression
| DivisionExpression Expression Expression -} -- | VariableExpression VariableAccess
deriving Eq deriving Eq
instance Show Expression instance Show Expression
@ -130,8 +130,8 @@ instance Show Expression
show (SubtractionExpression lhs rhs) = concat [show lhs, " - ", show rhs] show (SubtractionExpression lhs rhs) = concat [show lhs, " - ", show rhs]
show (NegationExpression negation) = '-' : show negation show (NegationExpression negation) = '-' : show negation
show (ProductExpression lhs rhs) = concat [show lhs, " * ", show rhs] 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 data VariableAccess
= VariableAccess Identifier = VariableAccess Identifier

View File

@ -147,11 +147,11 @@ expression globalTable (AST.NegationExpression negation) =
expression globalTable (AST.ProductExpression lhs rhs) expression globalTable (AST.ProductExpression lhs rhs)
= expression globalTable lhs = expression globalTable lhs
>> expression globalTable rhs >> expression globalTable rhs
{- expression globalTable (AST.VariableExpression variableExpression) =
variableAccess globalTable variableExpression
expression globalTable (AST.DivisionExpression lhs rhs) expression globalTable (AST.DivisionExpression lhs rhs)
= expression globalTable lhs = expression globalTable lhs
>> expression globalTable rhs >> expression globalTable rhs
{- expression globalTable (AST.VariableExpression variableExpression) =
variableAccess globalTable variableExpression
-} -}
statement :: SymbolTable -> AST.Statement -> NameAnalysis () statement :: SymbolTable -> AST.Statement -> NameAnalysis ()
statement _ AST.EmptyStatement = pure () statement _ AST.EmptyStatement = pure ()

View File

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

View File

@ -235,6 +235,8 @@ expression localTable = \case
) )
(AST.ProductExpression lhs rhs) -> (AST.ProductExpression lhs rhs) ->
binaryExpression ProductQuadruple lhs rhs binaryExpression ProductQuadruple lhs rhs
(AST.DivisionExpression lhs rhs) ->
binaryExpression DivisionQuadruple lhs rhs
{- (AST.VariableExpression variableExpression) -> do {- (AST.VariableExpression variableExpression) -> do
let variableType' = variableType variableExpression localTable let variableType' = variableType variableExpression localTable
variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty variableAccess' <- variableAccess localTable variableExpression Nothing variableType' mempty
@ -247,9 +249,7 @@ expression localTable = \case
pure pure
( VariableOperand arrayAddress ( VariableOperand arrayAddress
, Vector.snoc statements arrayStatement , Vector.snoc statements arrayStatement
) ) -}
(AST.DivisionExpression lhs rhs) ->
binaryExpression DivisionQuadruple lhs rhs -}
where where
binaryExpression f lhs rhs = do binaryExpression f lhs rhs = do
(lhsOperand, lhsStatements) <- expression localTable lhs (lhsOperand, lhsStatements) <- expression localTable lhs

View File

@ -29,7 +29,15 @@ data Statement
riscVConfiguration :: MachineConfiguration RiscV.XRegister riscVConfiguration :: MachineConfiguration RiscV.XRegister
riscVConfiguration = MachineConfiguration 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 type RiscVStore = Store RiscV.XRegister
@ -158,6 +166,35 @@ quadruple (ProductQuadruple operand1 operand2 (Store register))
$ RiscV.BaseInstruction RiscV.Op $ RiscV.BaseInstruction RiscV.Op
$ RiscV.R register RiscV.MUL register operandRegister $ RiscV.R register RiscV.MUL register operandRegister
$ RiscV.Funct7 0b0000001 $ 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 :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
loadImmediateOrRegister (IntOperand intValue) targetRegister = 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 .global exit
.type exit, @function .type exit, @function
.global _divide_by_zero_error
.type _divide_by_zero_error, @function
.global _start .global _start
.type _start, @function .type _start, @function
@ -51,7 +54,7 @@ printi:
addi a0, zero, 1 addi a0, zero, 1
addi a1, a1, 1 addi a1, a1, 1
sub a2, s0, a1 sub a2, s0, a1
addi a7, zero, 64 addi a7, zero, 64 # write
ecall ecall
lw s0, 0(sp) lw s0, 0(sp)
@ -74,7 +77,7 @@ printc:
addi a0, zero, 1 addi a0, zero, 1
addi a1, s0, -2 addi a1, s0, -2
addi a2, zero, 2 addi a2, zero, 2
addi a7, zero, 64 addi a7, zero, 64 # write
ecall ecall
lw s0, 0(sp) lw s0, 0(sp)
@ -84,10 +87,19 @@ printc:
exit: exit:
addi a0, zero, 0 addi a0, zero, 0
addi a7, zero, 93 addi a7, zero, 93 # exit
ecall ecall
# ret # ret
_divide_by_zero_error:
addi a7, zero, 172 # getpid
ecall
addi a1, zero, 8 # SIGFPE
addi a7, zero, 129 # kill
ecall
ret
_start: _start:
call main call main
call exit call exit