summaryrefslogtreecommitdiff
path: root/lib/Language/Elna/CodeGenerator.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Language/Elna/CodeGenerator.hs')
-rw-r--r--lib/Language/Elna/CodeGenerator.hs34
1 files changed, 22 insertions, 12 deletions
diff --git a/lib/Language/Elna/CodeGenerator.hs b/lib/Language/Elna/CodeGenerator.hs
index 2e9b7a4..7df93d5 100644
--- a/lib/Language/Elna/CodeGenerator.hs
+++ b/lib/Language/Elna/CodeGenerator.hs
@@ -1,6 +1,7 @@
module Language.Elna.CodeGenerator
( Statement(..)
- , generateCode
+ , generateRiscV
+ , riscVConfiguration
) where
import Data.ByteString (ByteString)
@@ -10,10 +11,10 @@ import Data.Int (Int32)
import Data.Vector (Vector)
import qualified Data.Vector as Vector
import qualified Data.Text.Encoding as Text.Encoding
+import Language.Elna.Allocator (MachineConfiguration(..), Store(..))
import Language.Elna.Location (Identifier(..))
-import Language.Elna.Intermediate (Operand(..), Quadruple(..), Variable(..))
+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
@@ -26,15 +27,24 @@ data Statement
| JumpLabel ByteString [Directive]
deriving Eq
-generateCode :: SymbolTable -> HashMap Identifier (Vector Quadruple) -> Vector Statement
-generateCode _ = HashMap.foldlWithKey' go Vector.empty
+riscVConfiguration :: MachineConfiguration RiscV.XRegister
+riscVConfiguration = MachineConfiguration
+ { temporaryRegister = RiscV.T0
+ }
+
+type RiscVStore = Store RiscV.XRegister
+type RiscVQuadruple = Quadruple RiscVStore
+type RiscVOperand = Operand RiscVStore
+
+generateRiscV :: HashMap Identifier (Vector RiscVQuadruple) -> Vector Statement
+generateRiscV = HashMap.foldlWithKey' go Vector.empty
where
go accumulator (Identifier key) value =
let code = Vector.cons (JumpLabel (Text.Encoding.encodeUtf8 key) [GlobalDirective, FunctionDirective])
$ Vector.foldMap quadruple value
in accumulator <> code
-quadruple :: Quadruple -> Vector Statement
+quadruple :: RiscVQuadruple -> 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)
@@ -57,25 +67,25 @@ quadruple StopQuadruple = Vector.fromList
, Instruction (RiscV.BaseInstruction RiscV.OpImm $ RiscV.I RiscV.SP RiscV.ADDI RiscV.SP 4)
, Instruction (RiscV.BaseInstruction RiscV.Jalr $ RiscV.I RiscV.RA RiscV.JALR RiscV.Zero 0)
]
-quadruple (AddQuadruple operand1 operand2 (TempVariable _)) =
+quadruple (AddQuadruple operand1 operand2 (Store register)) =
let (operandRegister1, statements1) = loadImmediateOrRegister operand1 RiscV.A0
(operandRegister2, statements2) = loadImmediateOrRegister operand2 RiscV.A1
in Vector.snoc (statements1 <> statements2)
$ Instruction
$ RiscV.BaseInstruction RiscV.Op
- $ RiscV.R RiscV.T0 RiscV.ADD operandRegister1 operandRegister2 (RiscV.Funct7 0b0000000)
-quadruple (SubtractionQuadruple operand1 operand2 (TempVariable _)) =
+ $ RiscV.R register RiscV.ADD operandRegister1 operandRegister2 (RiscV.Funct7 0b0000000)
+quadruple (SubtractionQuadruple operand1 operand2 (Store register)) =
let (operandRegister1, statements1) = loadImmediateOrRegister operand1 RiscV.A0
(operandRegister2, statements2) = loadImmediateOrRegister operand2 RiscV.A1
in Vector.snoc (statements1 <> statements2)
$ Instruction
$ RiscV.BaseInstruction RiscV.Op
- $ RiscV.R RiscV.T0 RiscV.SUB operandRegister1 operandRegister2 (RiscV.Funct7 0b0100000)
+ $ RiscV.R register RiscV.SUB operandRegister1 operandRegister2 (RiscV.Funct7 0b0100000)
-loadImmediateOrRegister :: Operand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
+loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
loadImmediateOrRegister (IntOperand intValue) targetRegister =
(targetRegister, lui intValue targetRegister)
-loadImmediateOrRegister (VariableOperand _) _ = (RiscV.T0, Vector.empty)
+loadImmediateOrRegister (VariableOperand (Store register)) _ = (register, Vector.empty)
lui :: Int32 -> RiscV.XRegister -> Vector Statement
lui intValue targetRegister