Print numbers with multiple digits

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

11
TODO
View File

@ -1,8 +1,9 @@
# 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?
- To access named parameters and local variables 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
@ -16,4 +17,6 @@
# Built-in
Printi should be able to print numbers with multiple digits.
Printi should print a sign for negative numbers.
# Type analysis

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
@ -39,9 +40,31 @@ quadruple StartQuadruple = Vector.fromList
, 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)
]
quadruple (ParameterQuadruple _) = mempty
quadruple (CallQuadruple callName _) = Vector.singleton
$ Instruction (RiscV.CallInstruction callName)
quadruple (ParameterQuadruple (IntOperand intValue))
= mappend go
$ 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.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 numberOfArguments) = Vector.fromList
[ Instruction (RiscV.CallInstruction callName)
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP (numberOfArguments * 4))
]
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)

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: