summaryrefslogtreecommitdiff
path: root/lib/Language
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Language')
-rw-r--r--lib/Language/Elna/Allocator.hs3
-rw-r--r--lib/Language/Elna/CodeGenerator.hs31
2 files changed, 30 insertions, 4 deletions
diff --git a/lib/Language/Elna/Allocator.hs b/lib/Language/Elna/Allocator.hs
new file mode 100644
index 0000000..a5ca574
--- /dev/null
+++ b/lib/Language/Elna/Allocator.hs
@@ -0,0 +1,3 @@
+module Language.Elna.Allocator
+ (
+ ) where
diff --git a/lib/Language/Elna/CodeGenerator.hs b/lib/Language/Elna/CodeGenerator.hs
index 3cb5c1d..1a9151a 100644
--- a/lib/Language/Elna/CodeGenerator.hs
+++ b/lib/Language/Elna/CodeGenerator.hs
@@ -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)