diff --git a/lib/Language/Elna/CodeGenerator.hs b/lib/Language/Elna/CodeGenerator.hs index 7df93d5..a561cb8 100644 --- a/lib/Language/Elna/CodeGenerator.hs +++ b/lib/Language/Elna/CodeGenerator.hs @@ -67,20 +67,58 @@ 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 (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 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 register RiscV.SUB operandRegister1 operandRegister2 (RiscV.Funct7 0b0100000) +quadruple (AddQuadruple operand1 operand2 (Store register)) + | IntOperand immediateOperand1 <- operand1 + , IntOperand immediateOperand2 <- operand2 = + lui (immediateOperand1 + immediateOperand2) register + | VariableOperand variableOperand1 <- operand1 + , VariableOperand variableOperand2 <- operand2 = + let Store operandRegister1 = variableOperand1 + Store operandRegister2 = variableOperand2 + in pure $ Instruction + $ RiscV.BaseInstruction RiscV.Op + $ RiscV.R register RiscV.ADD operandRegister1 operandRegister2 (RiscV.Funct7 0b0000000) + | VariableOperand variableOperand1 <- operand1 + , IntOperand immediateOperand2 <- operand2 = + addImmediateRegister variableOperand1 immediateOperand2 + | IntOperand immediateOperand1 <- operand1 + , VariableOperand variableOperand2 <- operand2 = + addImmediateRegister variableOperand2 immediateOperand1 + where + addImmediateRegister variableOperand immediateOperand = + let statements = lui immediateOperand register + Store operandRegister = variableOperand + in Vector.snoc statements + $ Instruction + $ RiscV.BaseInstruction RiscV.Op + $ RiscV.R register RiscV.ADD register operandRegister (RiscV.Funct7 0b0000000) +quadruple (SubtractionQuadruple operand1 operand2 (Store register)) + | IntOperand immediateOperand1 <- operand1 + , IntOperand immediateOperand2 <- operand2 = + lui (immediateOperand1 - immediateOperand2) register + | VariableOperand variableOperand1 <- operand1 + , VariableOperand variableOperand2 <- operand2 = + let Store operandRegister1 = variableOperand1 + Store operandRegister2 = variableOperand2 + in pure $ Instruction + $ RiscV.BaseInstruction RiscV.Op + $ RiscV.R register RiscV.SUB operandRegister1 operandRegister2 (RiscV.Funct7 0b0100000) + | IntOperand immediateOperand1 <- operand1 + , VariableOperand variableOperand2 <- operand2 = + let statements1 = lui immediateOperand1 register + Store operandRegister2 = variableOperand2 + in Vector.snoc statements1 + $ Instruction + $ RiscV.BaseInstruction RiscV.Op + $ RiscV.R register RiscV.SUB register operandRegister2 (RiscV.Funct7 0b0100000) + | VariableOperand variableOperand1 <- operand1 + , IntOperand immediateOperand2 <- operand2 = + let statements2 = lui (negate immediateOperand2) register + Store operandRegister1 = variableOperand1 + in Vector.snoc statements2 + $ Instruction + $ RiscV.BaseInstruction RiscV.Op + $ RiscV.R register RiscV.ADD register operandRegister1 (RiscV.Funct7 0b0000000) loadImmediateOrRegister :: RiscVOperand -> RiscV.XRegister -> (RiscV.XRegister, Vector Statement) loadImmediateOrRegister (IntOperand intValue) targetRegister =