diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 87974258359..c1661a67cbc 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -125,8 +125,12 @@ internal class CodeGenerator(override val context:Context) : ContextUtils { fun div (arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildSDiv(context.llvmBuilder, arg0, arg1, result)!! fun srem (arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildSRem(context.llvmBuilder, arg0, arg1, result)!! + /* integers comparisons */ fun icmpEq(arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntEQ, arg0, arg1, result)!! + /* floating-point comparisons */ + fun fcmpEq(arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildFCmp(context.llvmBuilder, LLVMRealPredicate.LLVMRealOEQ, arg0, arg1, result)!! + fun bitcast(type: LLVMOpaqueType?, value: LLVMOpaqueValue, result: String) = LLVMBuildBitCast(context.llvmBuilder, value, type, result) fun alloca(type: KotlinType, varName: String):LLVMOpaqueValue = alloca( getLLVMType(type), varName) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 72f66d7dbbf..00a95ded86f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -17,7 +17,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrSetVariableImpl import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid - +import org.jetbrains.kotlin.name.Name fun emitLLVM(module: IrModuleFragment, runtimeFile: String, outFile: String) { @@ -395,11 +395,10 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid private fun evaluateFunctionCall(tmpVariableName: String, callee: IrCall, args: MutableList): LLVMOpaqueValue? { val descriptor:FunctionDescriptor = callee.descriptor as FunctionDescriptor - when { - descriptor.isOperator -> return evaluateOperatorCall(tmpVariableName, callee.origin!!, args) - descriptor is IrBuiltinOperatorDescriptorBase -> return evaluateOperatorCall(tmpVariableName, callee.origin!!, args) - descriptor is ClassConstructorDescriptor -> return evaluateConstructorCall(tmpVariableName, callee, args) - else -> return evaluateSimpleFunctionCall(tmpVariableName, descriptor, args) + when (descriptor) { + is IrBuiltinOperatorDescriptorBase -> return evaluateOperatorCall (tmpVariableName, callee, args) + is ClassConstructorDescriptor -> return evaluateConstructorCall (tmpVariableName, callee, args) + else -> return evaluateSimpleFunctionCall(tmpVariableName, descriptor, args) } } @@ -419,24 +418,33 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid } //-------------------------------------------------------------------------// + private val EQEQ = Name.identifier("EQEQ") - private fun evaluateOperatorCall(tmpVariableName: String, origin: IrStatementOrigin, args: MutableList): LLVMOpaqueValue { - logger.log("evaluateCall $tmpVariableName origin:$origin") - when (origin) { - IrStatementOrigin.PLUS -> return generator.plus (args[0]!!, args[1]!!, tmpVariableName) - IrStatementOrigin.MINUS -> return generator.minus (args[0]!!, args[1]!!, tmpVariableName) - IrStatementOrigin.PLUSEQ -> return generator.plus (args[0]!!, args[1]!!, tmpVariableName) - IrStatementOrigin.MINUSEQ -> return generator.minus (args[0]!!, args[1]!!, tmpVariableName) - IrStatementOrigin.MUL -> return generator.mul (args[0]!!, args[1]!!, tmpVariableName) - IrStatementOrigin.DIV -> return generator.div (args[0]!!, args[1]!!, tmpVariableName) - IrStatementOrigin.PERC -> return generator.srem (args[0]!!, args[1]!!, tmpVariableName) - IrStatementOrigin.EQEQ -> return generator.icmpEq(args[0]!!, args[1]!!, tmpVariableName) + private fun evaluateOperatorCall(tmpVariableName: String, callee: IrCall, args: MutableList): LLVMOpaqueValue { + logger.log("evaluateCall $tmpVariableName origin:$callee") + val descriptor = callee.descriptor + when (descriptor.name) { + EQEQ -> return evaluateOperatorEqeq(callee as IrBinaryPrimitiveImpl, args[0]!!, args[1]!!, tmpVariableName) else -> { TODO() } } } + private fun evaluateOperatorEqeq(callee: IrBinaryPrimitiveImpl, arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, tmpVariableName: String):LLVMOpaqueValue { + val operandType = callee.argument0.type + assert(operandType == callee.argument1.type) + when { + KotlinBuiltIns.isByte (operandType) -> return generator.icmpEq(arg0, arg1, tmpVariableName) + KotlinBuiltIns.isShort (operandType) -> return generator.icmpEq(arg0, arg1, tmpVariableName) + KotlinBuiltIns.isInt (operandType) -> return generator.icmpEq(arg0, arg1, tmpVariableName) + KotlinBuiltIns.isLong (operandType) -> return generator.icmpEq(arg0, arg1, tmpVariableName) + KotlinBuiltIns.isFloat (operandType) -> return generator.fcmpEq(arg0, arg1, tmpVariableName) + KotlinBuiltIns.isDouble(operandType) -> return generator.fcmpEq(arg0, arg1, tmpVariableName) + else -> TODO("ComplexType") + } + } + //-------------------------------------------------------------------------// private fun generateWhenCase(branch: IrBranch, bbNext: LLVMOpaqueBasicBlock?, bbExit: LLVMOpaqueBasicBlock?) {