diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt index 9342d947e69..4cb18ed8cf2 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt @@ -466,6 +466,41 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM return left } + fun addPrimitiveReferenceOperation(referenceName: KtSimpleNameExpression, firstOp: LLVMSingleValue, secondNativeOp: LLVMSingleValue): LLVMExpression { + val firstNativeOp = codeBuilder.receiveNativeValue(firstOp) + return when (referenceName.getReferencedName()) { + "or" -> firstNativeOp.type!!.operatorOr(firstNativeOp, secondNativeOp) + "xor" -> firstNativeOp.type!!.operatorXor(firstNativeOp, secondNativeOp) + "and" -> firstNativeOp.type!!.operatorAnd(firstNativeOp, secondNativeOp) + "lhr" -> firstNativeOp.type!!.operatorShl(firstNativeOp, secondNativeOp) + "shr" -> firstNativeOp.type!!.operatorShr(firstNativeOp, secondNativeOp) + "ushr" -> firstNativeOp.type!!.operatorUshr(firstNativeOp, secondNativeOp) + "+=" -> { + val llvmExpression = firstNativeOp.type!!.operatorPlus(firstNativeOp, secondNativeOp) + val resultOp = codeBuilder.getNewVariable(llvmExpression.variableType) + codeBuilder.addAssignment(resultOp, llvmExpression) + codeBuilder.storeVariable(firstOp, resultOp) + return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}") + } + "-=" -> { + val llvmExpression = firstNativeOp.type!!.operatorMinus(firstNativeOp, secondNativeOp) + val resultOp = codeBuilder.getNewVariable(llvmExpression.variableType) + codeBuilder.addAssignment(resultOp, llvmExpression) + codeBuilder.storeVariable(firstOp, resultOp) + return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}") + } + "*=" -> { + val llvmExpression = firstNativeOp.type!!.operatorTimes(firstNativeOp, secondNativeOp) + val resultOp = codeBuilder.getNewVariable(llvmExpression.variableType) + codeBuilder.addAssignment(resultOp, llvmExpression) + codeBuilder.storeVariable(firstOp, resultOp) + return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}") + } + else -> throw UnsupportedOperationException("Unknown binary operator") + } + } + + private fun addPrimitiveBinaryOperation(operator: IElementType, referenceName: KtSimpleNameExpression?, firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMVariable { val firstNativeOp = codeBuilder.receiveNativeValue(firstOp) val secondNativeOp = codeBuilder.receiveNativeValue(secondOp) @@ -497,7 +532,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM codeBuilder.storeVariable(result, secondNativeOp) return result } - else -> codeBuilder.addPrimitiveReferenceOperation(referenceName!!, firstNativeOp, secondNativeOp) + else -> addPrimitiveReferenceOperation(referenceName!!, firstOp, secondNativeOp) } val resultOp = codeBuilder.getNewVariable(llvmExpression.variableType) codeBuilder.addAssignment(resultOp, llvmExpression) @@ -741,7 +776,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM private fun genReferenceReturn(retVar: LLVMSingleValue) { var result = retVar if (result.pointer == 2) { - result = codeBuilder.loadAndGetVariable(retVar as LLVMVariable) + result = codeBuilder.loadAndGetVariable(retVar as LLVMVariable) } codeBuilder.storeVariable(returnType!!, result) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt index 9a0a3deb332..3f310df5967 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -56,18 +56,6 @@ class LLVMBuilder(val arm: Boolean) { else -> throw UnsupportedOperationException() } - fun addPrimitiveReferenceOperation(referenceName: KtSimpleNameExpression, firstNativeOp: LLVMSingleValue, secondNativeOp: LLVMSingleValue): LLVMExpression { - return when (referenceName.getReferencedName()) { - "or" -> firstNativeOp.type!!.operatorOr(firstNativeOp, secondNativeOp) - "xor" -> firstNativeOp.type!!.operatorXor(firstNativeOp, secondNativeOp) - "and" -> firstNativeOp.type!!.operatorAnd(firstNativeOp, secondNativeOp) - "lhr" -> firstNativeOp.type!!.operatorShl(firstNativeOp, secondNativeOp) - "shr" -> firstNativeOp.type!!.operatorShr(firstNativeOp, secondNativeOp) - "ushr" -> firstNativeOp.type!!.operatorUshr(firstNativeOp, secondNativeOp) - else -> throw UnsupportedOperationException("Unknown binary operator") - } - } - fun clean() { localCode = StringBuilder() globalCode = StringBuilder() diff --git a/translator/src/test/kotlin/tests/input/assignment_operators_1.txt b/translator/src/test/kotlin/tests/input/assignment_operators_1.txt new file mode 100644 index 00000000000..e1d861a6018 --- /dev/null +++ b/translator/src/test/kotlin/tests/input/assignment_operators_1.txt @@ -0,0 +1,3 @@ +assignment_operators_1_plus_Int(11) == 17 +assignment_operators_1_minus_Int(11) == 5 +assignment_operators_1_times_Int(11) == 66 diff --git a/translator/src/test/kotlin/tests/kotlin/assignment_operators_1.kt b/translator/src/test/kotlin/tests/kotlin/assignment_operators_1.kt new file mode 100644 index 00000000000..7e05899e992 --- /dev/null +++ b/translator/src/test/kotlin/tests/kotlin/assignment_operators_1.kt @@ -0,0 +1,17 @@ +fun assignment_operators_1_plus(x: Int): Int { + var nzk = x + nzk += 6 + return nzk +} + +fun assignment_operators_1_minus(x: Int): Int { + var nzk = x + nzk -= 6 + return nzk +} + +fun assignment_operators_1_times(x: Int): Int { + var nzk = x + nzk *= 6 + return nzk +} \ No newline at end of file