Print numbers with multiple digits

This commit is contained in:
Eugen Wissner 2024-09-27 00:22:44 +02:00
parent 8eaeb5afa3
commit f26424acfb
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
9 changed files with 73 additions and 27 deletions

12
TODO
View File

@ -1,8 +1,12 @@
# Intermediate code generation
- Calculate maximum number of arguments that a function can have. Put procedure
arguments onto the stack, above the stack pointer. Should the offsets be
calculated during IR generation or target code generation?
- All procedure calls a generated with a single arguments. To support more
arguments they should be put onto the stack, above the stack pointer.
The stack can grow on demand and then be cleaned up (the call instruction
contains the number of arguments, so the stack size can be reduced), or the
function with most arguments can be found and the stack size allocated.
To access the arguments inside a procedure, the information about argument
names should be kept somewhere.
# ELF generation
@ -16,4 +20,4 @@
# Built-in
Printi should be able to print numbers with multiple digits.
Printi should print a sign for negative numbers.

View File

@ -35,6 +35,7 @@ common warnings
library elna-internal
import: warnings
exposed-modules:
Language.Elna.Allocator
Language.Elna.Architecture.RiscV
Language.Elna.AST
Language.Elna.CodeGenerator

View File

@ -0,0 +1,3 @@
module Language.Elna.Allocator
(
) where

View File

@ -10,9 +10,10 @@ import Data.Vector (Vector)
import qualified Data.Vector as Vector
import qualified Data.Text.Encoding as Text.Encoding
import Language.Elna.Location (Identifier(..))
import Language.Elna.Intermediate (Quadruple(..))
import Language.Elna.Intermediate (Operand(..), Quadruple(..))
import qualified Language.Elna.Architecture.RiscV as RiscV
import Language.Elna.SymbolTable (SymbolTable)
import Data.Bits (Bits(..))
data Directive
= GlobalDirective
@ -34,17 +35,34 @@ generateCode _ = HashMap.foldlWithKey' go Vector.empty
quadruple :: Quadruple -> Vector Statement
quadruple StartQuadruple = Vector.fromList
[ Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP (negate 4))
, Instruction (RiscV.BaseInstruction RiscV.Store $ RiscV.S 0 RiscV.SW RiscV.SP RiscV.S0)
, Instruction (RiscV.BaseInstruction RiscV.Store $ RiscV.S 4 RiscV.SW RiscV.SP RiscV.RA)
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.S0 RiscV.ADDI RiscV.SP 4)
[ Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP (negate 8))
, Instruction (RiscV.BaseInstruction RiscV.Store $ RiscV.S 4 RiscV.SW RiscV.SP RiscV.S0)
, Instruction (RiscV.BaseInstruction RiscV.Store $ RiscV.S 8 RiscV.SW RiscV.SP RiscV.RA)
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.S0 RiscV.ADDI RiscV.SP 8)
]
quadruple (ParameterQuadruple _) = mempty
quadruple (ParameterQuadruple (IntOperand intValue))
= Vector.snoc go
$ Instruction (RiscV.BaseInstruction RiscV.Store $ RiscV.S 0 RiscV.SW RiscV.SP RiscV.A0)
where
hi = intValue `shiftR` 12
lo = intValue
go
| intValue >= -2048
, intValue <= 2047 = Vector.singleton
$ Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.A0 RiscV.ADDI RiscV.A0 $ fromIntegral lo)
| intValue .&. 0x800 /= 0 = Vector.fromList
[ Instruction (RiscV.BaseInstruction RiscV.Lui $ RiscV.U RiscV.A0 $ fromIntegral $ succ hi)
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.A0 RiscV.ADDI RiscV.A0 $ fromIntegral lo)
]
| otherwise = Vector.fromList
[ Instruction (RiscV.BaseInstruction RiscV.Lui $ RiscV.U RiscV.A0 $ fromIntegral hi)
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.A0 RiscV.ADDI RiscV.A0 $ fromIntegral lo)
]
quadruple (CallQuadruple callName _) = Vector.singleton
$ Instruction (RiscV.CallInstruction callName)
quadruple StopQuadruple = Vector.fromList
[ Instruction (RiscV.BaseInstruction RiscV.Load $ RiscV.I RiscV.S0 RiscV.LW RiscV.SP 0)
, Instruction (RiscV.BaseInstruction RiscV.Load $ RiscV.I RiscV.RA RiscV.LW RiscV.SP 4)
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP 4)
[ Instruction (RiscV.BaseInstruction RiscV.Load $ RiscV.I RiscV.S0 RiscV.LW RiscV.SP 4)
, Instruction (RiscV.BaseInstruction RiscV.Load $ RiscV.I RiscV.RA RiscV.LW RiscV.SP 8)
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP 8)
, Instruction (RiscV.BaseInstruction RiscV.Jalr $ RiscV.I RiscV.RA RiscV.JALR RiscV.Zero 0)
]

View File

@ -0,0 +1 @@
13

View File

@ -0,0 +1 @@
2097150

View File

@ -0,0 +1,3 @@
proc main() {
printi(13);
}

View File

@ -0,0 +1,3 @@
proc main() {
printi(2097150);
}

View File

@ -6,29 +6,41 @@
.text
printi:
addi sp, sp, -4
addi sp, sp, -16
sw s0, 0(sp)
sw ra, 4(sp)
addi s0, sp, 4
addi s0, sp, 16
addi t1, zero, '\n'
sb t1, -1(s0)
# t0 - Whole number.
# t1 - Constant 10.
# a1 - Local buffer.
# t2 - Current character.
lw t0, 0(s0)
addi t1, zero, 10
addi a1, s0, -2
.digit10:
rem t2, t0, t1
addi t2, t2, '0'
sb t2, 0(a1)
div t0, t0, t1
addi a1, a1, -1
bne zero, t0, .digit10
addi t0, a0, 0
addi a0, a0, '0'
sw a0, 0(s0)
addi a0, x0, 1
addi a1, s0, 0
addi a2, x0, 1
addi a7, x0, 64
ecall
addi t1, x0, '\n'
sw t1, 0(s0)
addi a0, zero, 1
addi a1, a1, 1
sub a2, s0, a1
addi a7, zero, 64
ecall
addi a0, t0, 0
lw s0, 0(sp)
lw ra, 4(sp)
addi sp, sp, 4
addi sp, sp, 16
ret
_start: