diff options
Diffstat (limited to 'lib/Language/Elna/CodeGenerator.hs')
| -rw-r--r-- | lib/Language/Elna/CodeGenerator.hs | 34 |
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 |
