Implement if statements with equality
This commit is contained in:
@ -13,7 +13,7 @@ import Data.Vector (Vector)
|
||||
import qualified Data.Vector as Vector
|
||||
import qualified Language.Elna.Architecture.RiscV as RiscV
|
||||
import Language.Elna.Backend.Allocator (MachineConfiguration(..), Store(..))
|
||||
import Language.Elna.Backend.Intermediate (Operand(..), Quadruple(..))
|
||||
import Language.Elna.Backend.Intermediate (Label(..), Operand(..), Quadruple(..))
|
||||
import Language.Elna.Location (Identifier(..))
|
||||
import Data.Bits (Bits(..))
|
||||
import Data.Foldable (Foldable(..), foldlM)
|
||||
@ -45,6 +45,10 @@ riscVConfiguration = MachineConfiguration
|
||||
]
|
||||
}
|
||||
|
||||
-- | Reserved register used for calculations to save an immediate temporary.
|
||||
immediateRegister :: RiscV.XRegister
|
||||
immediateRegister = RiscV.A7
|
||||
|
||||
type RiscVStore = Store RiscV.XRegister
|
||||
type RiscVQuadruple = Quadruple RiscVStore
|
||||
type RiscVOperand = Operand RiscVStore
|
||||
@ -243,6 +247,43 @@ quadruple (DivisionQuadruple operand1 operand2 (Store register))
|
||||
$ RiscV.BaseInstruction RiscV.Op
|
||||
$ RiscV.R register RiscV.DIV register operandRegister2
|
||||
$ RiscV.Funct7 0b0000001
|
||||
quadruple (LabelQuadruple (Label label)) = pure $ Vector.singleton $ JumpLabel label mempty
|
||||
quadruple (GoToQuadruple label) = pure $ Vector.singleton $ unconditionalJal label
|
||||
quadruple (EqualQuadruple operand1 operand2 goToLabel)
|
||||
| IntOperand immediateOperand1 <- operand1
|
||||
, IntOperand immediateOperand2 <- operand2 =
|
||||
if immediateOperand1 == immediateOperand2
|
||||
then pure $ Vector.singleton $ unconditionalJal goToLabel
|
||||
else pure Vector.empty
|
||||
| VariableOperand variableOperand1 <- operand1
|
||||
, VariableOperand variableOperand2 <- operand2 = do
|
||||
let Store operandRegister1 = variableOperand1
|
||||
Store operandRegister2 = variableOperand2
|
||||
branchLabel <- createLabel
|
||||
pure $ Vector.singleton
|
||||
$ Instruction
|
||||
$ RiscV.RelocatableInstruction RiscV.Branch
|
||||
$ RiscV.RBranch branchLabel RiscV.BEQ operandRegister1 operandRegister2
|
||||
| VariableOperand variableOperand1 <- operand1
|
||||
, IntOperand immediateOperand2 <- operand2 =
|
||||
compareImmediateRegister variableOperand1 immediateOperand2
|
||||
| IntOperand immediateOperand1 <- operand1
|
||||
, VariableOperand variableOperand2 <- operand2 =
|
||||
compareImmediateRegister variableOperand2 immediateOperand1
|
||||
where
|
||||
compareImmediateRegister variableOperand immediateOperand =
|
||||
let statements = lui immediateOperand immediateRegister
|
||||
Store operandRegister = variableOperand
|
||||
Label goToLabel' = goToLabel
|
||||
in pure $ Vector.snoc statements
|
||||
$ Instruction
|
||||
$ RiscV.RelocatableInstruction RiscV.Branch
|
||||
$ RiscV.RBranch goToLabel' RiscV.BEQ operandRegister immediateRegister
|
||||
|
||||
unconditionalJal :: Label -> Statement
|
||||
unconditionalJal (Label goToLabel) = Instruction
|
||||
$ RiscV.RelocatableInstruction RiscV.Jal
|
||||
$ RiscV.RJal RiscV.Zero goToLabel
|
||||
|
||||
loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement)
|
||||
loadImmediateOrRegister (IntOperand intValue) targetRegister =
|
||||
|
@ -236,8 +236,8 @@ riscv32Elf code objectHandle = text
|
||||
, st_info = stInfo STB_GLOBAL STT_FUNC
|
||||
}
|
||||
result =
|
||||
( encoded <> encoded'
|
||||
, relocations <> relocations'
|
||||
( encoded'
|
||||
, relocations'
|
||||
, ElfHeaderResult (names <> Text.encodeUtf8 labelName <> "\0") (Vector.snoc symbols newEntry)
|
||||
, definitions'
|
||||
)
|
||||
@ -260,6 +260,9 @@ riscv32Elf code objectHandle = text
|
||||
| RiscV.RBranch symbolName _ _ _ <- instructionType
|
||||
-> Just -- R_RISCV_BRANCH
|
||||
$ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 16
|
||||
| RiscV.RJal _ symbolName <- instructionType
|
||||
-> Just -- R_RISCV_JAL
|
||||
$ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 17
|
||||
RiscV.CallInstruction symbolName
|
||||
-> Just -- R_RISCV_CALL_PLT
|
||||
$ UnresolvedRelocation (Text.encodeUtf8 symbolName) offset 19
|
||||
|
Reference in New Issue
Block a user