codegen: operator processing for primitive and other types

This commit is contained in:
Konstantin Anisimov
2016-11-08 18:35:19 +03:00
committed by vvlevchenko
parent 6c90ab1176
commit cb39f650f3
2 changed files with 29 additions and 17 deletions
@@ -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)
@@ -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?>): 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?>): 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?>): 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?) {