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 # Intermediate code generation
- Calculate maximum number of arguments that a function can have. Put procedure - To access named parameters and local variables inside a procedure, IR should
arguments onto the stack, above the stack pointer. Should the offsets be be able to reference them. During the generation the needed information (e.g.
calculated during IR generation or target code generation? offsets or registers) can be extracted from the symbol table and saved in the
operands.
# ELF generation # ELF generation
@ -16,4 +17,6 @@
# Built-in # 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 library elna-internal
import: warnings import: warnings
exposed-modules: exposed-modules:
Language.Elna.Allocator
Language.Elna.Architecture.RiscV Language.Elna.Architecture.RiscV
Language.Elna.AST Language.Elna.AST
Language.Elna.CodeGenerator 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.Vector as Vector
import qualified Data.Text.Encoding as Text.Encoding import qualified Data.Text.Encoding as Text.Encoding
import Language.Elna.Location (Identifier(..)) 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 qualified Language.Elna.Architecture.RiscV as RiscV
import Language.Elna.SymbolTable (SymbolTable) import Language.Elna.SymbolTable (SymbolTable)
import Data.Bits (Bits(..))
data Directive data Directive
= GlobalDirective = 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.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.S0 RiscV.ADDI RiscV.SP 4)
] ]
quadruple (ParameterQuadruple _) = mempty quadruple (ParameterQuadruple (IntOperand intValue))
quadruple (CallQuadruple callName _) = Vector.singleton = mappend go
$ Instruction (RiscV.CallInstruction callName) $ 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 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.S0 RiscV.LW RiscV.SP 0)
, Instruction (RiscV.BaseInstruction RiscV.Load $ RiscV.I RiscV.RA RiscV.LW RiscV.SP 4) , 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 .text
printi: printi:
addi sp, sp, -4 addi sp, sp, -16
sw s0, 0(sp) sw s0, 0(sp)
sw ra, 4(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 ecall
addi t1, x0, '\n' addi a0, zero, 1
sw t1, 0(s0) addi a1, a1, 1
sub a2, s0, a1
addi a7, zero, 64
ecall ecall
addi a0, t0, 0
lw s0, 0(sp) lw s0, 0(sp)
lw ra, 4(sp) lw ra, 4(sp)
addi sp, sp, 4 addi sp, sp, 16
ret ret
_start: _start: