From 2521b02f1440d2d99c4daac292b9f425322c06ba Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Tue, 30 Aug 2016 12:26:14 +0300 Subject: [PATCH] translator: refactor llvm types --- .../kotlinnative/translator/BlockCodegen.kt | 8 +- .../kotlinnative/translator/ClassCodegen.kt | 5 +- .../translator/FunctionCodegen.kt | 4 +- .../kotlinnative/translator/ObjectCodegen.kt | 3 +- .../translator/ProjectTranslator.kt | 6 +- .../kotlinnative/translator/StructCodegen.kt | 10 +- .../translator/llvm/LLVMBuilder.kt | 20 +-- .../translator/llvm/types/LLVMArray.kt | 6 +- .../translator/llvm/types/LLVMBooleanType.kt | 110 +++++++------ .../translator/llvm/types/LLVMByteType.kt | 24 +-- .../translator/llvm/types/LLVMCharType.kt | 58 +++---- .../translator/llvm/types/LLVMDoubleType.kt | 96 ++++++----- .../translator/llvm/types/LLVMFloatType.kt | 22 ++- .../translator/llvm/types/LLVMFunctionType.kt | 22 ++- .../translator/llvm/types/LLVMIntType.kt | 150 +++++++++--------- .../translator/llvm/types/LLVMLongType.kt | 77 +++++---- .../translator/llvm/types/LLVMNullType.kt | 3 +- .../llvm/types/LLVMReferenceType.kt | 7 +- .../translator/llvm/types/LLVMShortType.kt | 55 ++++--- .../translator/llvm/types/LLVMStringType.kt | 11 +- .../translator/llvm/types/LLVMType.kt | 51 +++--- .../translator/llvm/types/LLVMVoidType.kt | 3 +- 22 files changed, 360 insertions(+), 391 deletions(-) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt index 6de9080194c..eb0afefcb4b 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt @@ -253,7 +253,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va val names = parseArgList(selector, scopeDepth) val type = LLVMType.mangleFunctionArguments(names) - val constructedFunctionName = standardType.mangle() + nameWithoutMangling.addBeforeIfNotEmpty(".") + type + val constructedFunctionName = standardType.mangle + nameWithoutMangling.addBeforeIfNotEmpty(".") + type val targetExtension = state.extensionFunctions[standardType.toString()] val extensionCodegen = targetExtension?.get(packageNameFirst.addAfterIfNotEmpty(".") + constructedFunctionName) ?: @@ -360,7 +360,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va else -> { val arrayIndex = evaluateConstantExpression(expr.indexExpressions.first() as KtConstantExpression) val arrayReceivedVariable = codeBuilder.loadAndGetVariable(arrayNameVariable) - val arrayElementType = (arrayNameVariable.type as LLVMArray).basicType() + val arrayElementType = (arrayNameVariable.type as LLVMArray).arrayElementType val indexVariable = codeBuilder.getNewVariable(arrayElementType, pointer = 1) codeBuilder.loadVariableOffset(indexVariable, arrayReceivedVariable, arrayIndex) indexVariable @@ -666,7 +666,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va codeBuilder.addExceptionCall("KotlinNullPointerException") codeBuilder.addUnconditionalJump(notNullLabel) codeBuilder.markWithLabel(notNullLabel) - if (firstOp.type.isPrimitive()) { + if (firstOp.type.isPrimitive) { result = codeBuilder.downLoadArgument(firstOp, 0) as LLVMVariable } return result @@ -815,7 +815,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va val result = firstOp as LLVMVariable val sourceArgument: LLVMSingleValue - if ((firstOp.pointer == 2) && secondOp.type!!.isPrimitive() && (secondOp.pointer == 0)) { + if ((firstOp.pointer == 2) && secondOp.type!!.isPrimitive && (secondOp.pointer == 0)) { sourceArgument = codeBuilder.getNewVariable(secondOp.type!!, 1) codeBuilder.allocStaticVar(sourceArgument, asValue = true) codeBuilder.storeVariable(sourceArgument, secondOp) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt index b3b5b2b9514..4924fe66b01 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt @@ -16,9 +16,8 @@ class ClassCodegen(state: TranslationState, variableManager: VariableManager, val clazz: KtClass, codeBuilder: LLVMBuilder, - packageName: String, parentCodegen: StructCodegen? = null) : - StructCodegen(state, variableManager, clazz, codeBuilder, packageName, parentCodegen) { + StructCodegen(state, variableManager, clazz, codeBuilder, parentCodegen) { val annotation: Boolean val enum: Boolean @@ -79,7 +78,7 @@ class ClassCodegen(state: TranslationState, val companionObjectDescriptor = descriptor.companionObjectDescriptor if (companionObjectDescriptor != null) { val companionObject = clazz.getCompanionObjects().first() - companionObjectCodegen = ObjectCodegen(state, variableManager, companionObject, codeBuilder, packageName, this) + companionObjectCodegen = ObjectCodegen(state, variableManager, companionObject, codeBuilder, this) companionObjectCodegen!!.prepareForGenerate() } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 5e3a9c13f0d..d2daf653826 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -4,7 +4,6 @@ import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe @@ -21,7 +20,6 @@ class FunctionCodegen(state: TranslationState, variableManager: VariableManager, val function: KtNamedFunction, codeBuilder: LLVMBuilder, - val packageName: String, val parentCodegen: StructCodegen? = null) : BlockCodegen(state, variableManager, codeBuilder) { @@ -52,7 +50,7 @@ class FunctionCodegen(state: TranslationState, val receiverType = descriptor.extensionReceiverParameter!!.type val translatorType = LLVMMapStandardType(receiverType, state) val packageName = (function.containingFile as KtFile).packageFqName.asString() - functionNamePrefix = packageName.addAfterIfNotEmpty(".") + translatorType.mangle() + "." + functionNamePrefix = packageName.addAfterIfNotEmpty(".") + translatorType.mangle + "." val extensionFunctionsOfThisType = state.extensionFunctions.getOrDefault(translatorType.toString(), HashMap()) extensionFunctionsOfThisType.put(fullName, this) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt index e3c781c87fb..4501dddbacc 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt @@ -12,9 +12,8 @@ class ObjectCodegen(state: TranslationState, variableManager: VariableManager, val objectDeclaration: KtObjectDeclaration, codeBuilder: LLVMBuilder, - packageName: String, parentCodegen: StructCodegen? = null) : - StructCodegen(state, variableManager, objectDeclaration, codeBuilder, packageName, parentCodegen) { + StructCodegen(state, variableManager, objectDeclaration, codeBuilder, parentCodegen) { override var size: Int = 0 override val structName: String = objectDeclaration.fqName?.asString()!! override val type: LLVMReferenceType diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt index b442d8d48d3..dd3efc9e38f 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt @@ -18,7 +18,7 @@ class ProjectTranslator(val files: List, val state: TranslationState) { fun addFunctionDeclarations(file: KtFile) { val variableManager = VariableManager(state.globalVariableCollection) for (declaration in file.declarations.filter { it is KtNamedFunction }) { - val function = FunctionCodegen(state, variableManager, declaration as KtNamedFunction, codeBuilder, file.packageFqName.asString()) + val function = FunctionCodegen(state, variableManager, declaration as KtNamedFunction, codeBuilder) if (function.external) { state.externalFunctions.put(function.fullName, function) } else { @@ -30,7 +30,7 @@ class ProjectTranslator(val files: List, val state: TranslationState) { fun addClassDeclarations(file: KtFile) { val variableManager = VariableManager(state.globalVariableCollection) for (declaration in file.declarations.filter { it is KtClass }) { - val codegen = ClassCodegen(state, variableManager, declaration as KtClass, codeBuilder, file.packageFqName.asString()) + val codegen = ClassCodegen(state, variableManager, declaration as KtClass, codeBuilder) state.classes.put(codegen.structName, codegen) } } @@ -46,7 +46,7 @@ class ProjectTranslator(val files: List, val state: TranslationState) { fun addObjectDeclarations(file: KtFile) { val variableManager = VariableManager(state.globalVariableCollection) for (declaration in file.declarations.filter { it is KtObjectDeclaration }) { - val codegen = ObjectCodegen(state, variableManager, declaration as KtObjectDeclaration, codeBuilder, file.packageFqName.asString()) + val codegen = ObjectCodegen(state, variableManager, declaration as KtObjectDeclaration, codeBuilder) state.objects.put(codegen.structName, codegen) } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt index 1aaa9813708..ff834e8a4cd 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt @@ -17,7 +17,6 @@ abstract class StructCodegen(val state: TranslationState, val variableManager: VariableManager, val classOrObject: KtClassOrObject, val codeBuilder: LLVMBuilder, - val packageName: String, val parentCodegen: StructCodegen? = null) { val fields = ArrayList() @@ -40,7 +39,7 @@ abstract class StructCodegen(val state: TranslationState, generateStruct() for (declaration in classOrObject.declarations.filter { it is KtNamedFunction }) { - val function = FunctionCodegen(state, variableManager, declaration as KtNamedFunction, codeBuilder, packageName, this) + val function = FunctionCodegen(state, variableManager, declaration as KtNamedFunction, codeBuilder, this) methods.put(function.name, function) } } @@ -69,7 +68,7 @@ abstract class StructCodegen(val state: TranslationState, generateSecondaryConstructor(secondaryConstructor) } - val classVal = LLVMVariable("classvariable.this", type, pointer = if (type.isPrimitive()) 0 else 1) + val classVal = LLVMVariable("classvariable.this", type, pointer = if (type.isPrimitive) 0 else 1) variableManager.addVariable("this", classVal, 0) for (function in methods.values) { @@ -104,8 +103,7 @@ abstract class StructCodegen(val state: TranslationState, nestedClasses.put(declaration.fqName!!.asString(), ClassCodegen(state, VariableManager(state.globalVariableCollection), - declaration, codeBuilder, - packageName, this)) + declaration, codeBuilder, this)) } } } @@ -162,7 +160,7 @@ abstract class StructCodegen(val state: TranslationState, variableManager.addVariable("this", mainConstructorThis, 0) blockCodegen.evaluateCodeBlock(secondaryConstructor.bodyExpression, scopeDepth = 1) - generateReturn(codeBuilder.downLoadArgument(variableManager.get("this")!!, 1) as LLVMVariable) + generateReturn(codeBuilder.downLoadArgument(variableManager["this"]!!, 1) as LLVMVariable) codeBuilder.addAnyReturn(LLVMVoidType()) codeBuilder.addEndExpression() } 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 9e1da5c5efe..60d6c5b4444 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -16,7 +16,6 @@ class LLVMBuilder(val arm: Boolean = false) { private var unique = 0 fun generateUniqueString() = ".unique." + unique++ - } init { @@ -132,7 +131,7 @@ class LLVMBuilder(val arm: Boolean = false) { } fun addStringConstant(variable: LLVMVariable, value: String) = - addLLVMCodeToGlobalPlace("$variable = private unnamed_addr constant ${(variable.type as LLVMStringType).fullType()} c\"${value.replace("\"", "\\\"")}\\00\", align 1") + addLLVMCodeToGlobalPlace("$variable = private unnamed_addr constant ${(variable.type as LLVMStringType).fullArrayType} c\"${value.replace("\"", "\\\"")}\\00\", align 1") fun convertVariableToType(variable: LLVMSingleValue, targetType: LLVMType): LLVMSingleValue { @@ -154,7 +153,7 @@ class LLVMBuilder(val arm: Boolean = false) { fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) { val code = "store ${target.type} getelementptr inbounds (" + - "${(source.type as LLVMStringType).fullType()}* $source, i32 0, i32 $offset), ${target.getType()} $target, align ${source.type.align}" + "${(source.type as LLVMStringType).fullArrayType}* $source, i32 0, i32 $offset), ${target.getType()} $target, align ${source.type.align}" (target.type as LLVMStringType).isLoaded = true localCode.appendln(code) } @@ -167,12 +166,13 @@ class LLVMBuilder(val arm: Boolean = false) { addLLVMCodeToLocalPlace("${label.label}:") } - fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) = - if ((source.type is LLVMStringType) && (!(source.type as LLVMStringType).isLoaded)) { - storeString(target as LLVMVariable, source as LLVMVariable, 0) - } else { - addLLVMCodeToLocalPlace("store ${source.getType()} $source, ${target.getType()} $target, align ${source.type?.align!!}") - } + fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) { + if ((source.type is LLVMStringType) && (!(source.type as LLVMStringType).isLoaded)) { + storeString(target as LLVMVariable, source as LLVMVariable, 0) + } else { + addLLVMCodeToLocalPlace("store ${source.getType()} $source, ${target.getType()} $target, align ${source.type?.align!!}") + } + } fun storeExpression(target: LLVMSingleValue, expression: LLVMExpression): LLVMVariable { @@ -283,7 +283,7 @@ class LLVMBuilder(val arm: Boolean = false) { fun addExceptionCall(exceptionName: String) { val exception = exceptions[exceptionName] val printResult = getNewVariable(LLVMIntType(), pointer = 0) - addLLVMCodeToLocalPlace("$printResult = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds (${(exception!!.type as LLVMStringType).fullType()}* $exception, i32 0, i32 0))") + addLLVMCodeToLocalPlace("$printResult = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds (${(exception!!.type as LLVMStringType).fullArrayType}* $exception, i32 0, i32 0))") addFunctionCall(LLVMVariable("abort", LLVMVoidType(), scope = LLVMVariableScope()), emptyList()) } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMArray.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMArray.kt index 370b1370ea2..7176186a117 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMArray.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMArray.kt @@ -2,8 +2,8 @@ package org.kotlinnative.translator.llvm.types interface LLVMArray { - fun basicType(): LLVMType - fun fullType(): String - + val arrayElementType: LLVMType + val fullArrayType: String val length: Int + } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt index 4bf5f0b9f67..0b58f1dd43f 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt @@ -6,67 +6,63 @@ import org.kotlinnative.translator.llvm.LLVMSingleValue class LLVMBooleanType() : LLVMType() { - //TODO switch by types: int + double = int - override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "sub nsw i1 $firstOp, $secondOp") - - //TODO switch by types: int + double = int - override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "mul nsw i1 $firstOp, $secondOp") - - //TODO switch by types: int + double = int - override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "add nsw i1 $firstOp, $secondOp") - - override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "sdiv i1 $firstOp, $secondOp") - - override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp slt i1 $firstOp, $secondOp") - - override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sgt i1 $firstOp, $secondOp") - - override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sle i1 $firstOp, $secondOp") - - override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sge i1 $firstOp, $secondOp") - - override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp eq i1" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - - override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp ne i1" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - - override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "or i1 $firstOp, $secondOp") - - override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "and i1 $firstOp, $secondOp") - - override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "xor i1 $firstOp, $secondOp") - - override fun equals(other: Any?): Boolean { - return other is LLVMBooleanType - } - - override fun parseArg(inputArg: String) = when (inputArg.toLowerCase()) { - "true" -> "1" - "false" -> "0" - else -> throw IllegalArgumentException("Failed to parse boolean type") - } - - override fun mangle() = "Boolean" - override val align = 4 override var size: Int = 1 override val defaultValue = "0" - override fun isPrimitive() = true - + override val mangle = "Boolean" + override val isPrimitive = true override val typename = "i1" + + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "sub nsw i1 $firstOp, $secondOp") + + override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "mul nsw i1 $firstOp, $secondOp") + + override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "add nsw i1 $firstOp, $secondOp") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "sdiv i1 $firstOp, $secondOp") + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i1 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i1 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i1 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i1 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i1" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i1" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "or i1 $firstOp, $secondOp") + + override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "and i1 $firstOp, $secondOp") + + override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "xor i1 $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMBooleanType + + override fun parseArg(inputArg: String) = + when (inputArg.toLowerCase()) { + "true" -> "1" + "false" -> "0" + else -> throw IllegalArgumentException("Failed to parse boolean type") + } + override fun hashCode() = - mangle().hashCode() + mangle.hashCode() } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt index 0da474a927e..52f88bbf7f4 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt @@ -4,6 +4,14 @@ import org.kotlinnative.translator.llvm.LLVMExpression import org.kotlinnative.translator.llvm.LLVMSingleValue class LLVMByteType() : LLVMType() { + + override val align = 1 + override var size: Int = 1 + override val mangle = "Byte" + override val typename = "i8" + override val defaultValue = "0" + override val isPrimitive = true + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = LLVMExpression(LLVMBooleanType(), "icmp slt i8 $firstOp, $secondOp") @@ -25,18 +33,10 @@ class LLVMByteType() : LLVMType() { override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = LLVMExpression(LLVMByteType(), "srem i8 $firstOp, $secondOp") - override fun equals(other: Any?): Boolean { - return other is LLVMByteType - } + override fun equals(other: Any?) = + other is LLVMByteType - override fun mangle() = "Byte" - - override val align = 1 - override var size: Int = 1 - override val typename = "i8" - override val defaultValue = "0" - override fun isPrimitive() = true override fun hashCode() = - mangle().hashCode() + mangle.hashCode() -} +} \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt index e67012c1742..75dbd3bc2c5 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt @@ -4,38 +4,38 @@ import org.kotlinnative.translator.llvm.LLVMExpression import org.kotlinnative.translator.llvm.LLVMSingleValue class LLVMCharType() : LLVMType() { - override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp slt i8 $firstOp, $secondOp") - - override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sgt i8 $firstOp, $secondOp") - - override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sle i8 $firstOp, $secondOp") - - override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sge i8 $firstOp, $secondOp") - - override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp eq i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - - override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp ne i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - - override fun equals(other: Any?): Boolean { - return other is LLVMCharType - } - - override fun parseArg(inputArg: String) = inputArg.first().toInt().toString() - - override fun mangle() = "Char" override val align = 1 override var size: Int = 1 + override val mangle = "Char" override val typename = "i8" override val defaultValue = "0" - override fun isPrimitive() = true - override fun hashCode() = - mangle().hashCode() + override val isPrimitive = true -} + override fun parseArg(inputArg: String) = inputArg.first().toInt().toString() + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i8 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i8 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i8 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i8 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMCharType + + override fun hashCode() = + mangle.hashCode() + +} \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt index 5af05c9c76b..f2530e92d11 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt @@ -6,60 +6,56 @@ import org.kotlinnative.translator.llvm.LLVMSingleValue class LLVMDoubleType() : LLVMType() { - //TODO switch by types: int + double = int - override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMDoubleType(), "fsub double $firstOp, $secondOp") - - //TODO switch by types: int + double = int - override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMDoubleType(), "fmul double $firstOp, $secondOp") - - //TODO switch by types: int + double = int - override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, $secondOp") - - override fun operatorInc(firstOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, 1.0") - - override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMDoubleType(), "fdiv double $firstOp, $secondOp") - - override fun operatorDec(firstOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMDoubleType(), "fsub double $firstOp, 1.0") - - override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "fcmp olt double $firstOp, $secondOp") - - override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "fcmp ogt double $firstOp, $secondOp") - - override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "fcmp ole double i32 $firstOp, $secondOp") - - override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "fcmp oge double i32 $firstOp, $secondOp") - - override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "fcmp oeq double $firstOp, $secondOp") - - override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "fcmp one double $firstOp, $secondOp") - - override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMDoubleType(), "frem double $firstOp, $secondOp") - - override fun equals(other: Any?): Boolean { - return other is LLVMDoubleType - } - - override fun mangle() = "Double" - override val align = 8 override var size: Int = 8 + override val mangle = "Double" override val typename = "double" override val defaultValue = "0.0" - override fun isPrimitive() = true + override val isPrimitive = true + + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fsub double $firstOp, $secondOp") + + override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fmul double $firstOp, $secondOp") + + override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, $secondOp") + + override fun operatorInc(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, 1.0") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fdiv double $firstOp, $secondOp") + + override fun operatorDec(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fsub double $firstOp, 1.0") + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp olt double $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp ogt double $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp ole double i32 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp oge double i32 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp oeq double $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp one double $firstOp, $secondOp") + + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "frem double $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMDoubleType + override fun hashCode() = - mangle().hashCode() + mangle.hashCode() } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFloatType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFloatType.kt index 33f856ee2de..37b021e4c44 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFloatType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFloatType.kt @@ -6,15 +6,19 @@ import org.kotlinnative.translator.llvm.LLVMSingleValue class LLVMFloatType() : LLVMType() { - //TODO switch by types: int + double = int + override val align = 4 + override var size: Int = 4 + override val mangle = "Float" + override val typename = "float" + override val defaultValue = "0.0" + override val isPrimitive = true + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = LLVMExpression(LLVMFloatType(), "fsub float $firstOp, $secondOp") - //TODO switch by types: int + double = int override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = LLVMExpression(LLVMFloatType(), "fmul float $firstOp, $secondOp") - //TODO switch by types: int + double = int override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = LLVMExpression(LLVMFloatType(), "fadd float $firstOp, $secondOp") @@ -48,17 +52,9 @@ class LLVMFloatType() : LLVMType() { override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = LLVMExpression(LLVMFloatType(), "frem float $firstOp, $secondOp") - override fun equals(other: Any?): Boolean { - return other is LLVMFloatType - } + override fun equals(other: Any?) = + other is LLVMFloatType - override val align = 4 - override var size: Int = 4 - - override fun mangle() = "Float" - override val typename = "float" - override val defaultValue = "0.0" - override fun isPrimitive() = true override fun hashCode() = typename.hashCode() diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt index d7f0d863584..c7d96be575d 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt @@ -10,6 +10,8 @@ class LLVMFunctionType(type: KotlinType, state: TranslationState) : LLVMType() { override val defaultValue = "" override val align: Int = 4 override var size: Int = 4 + override val mangle: String + override val typename = "FunctionType" val arguments: List val returnType: LLVMVariable @@ -18,24 +20,18 @@ class LLVMFunctionType(type: KotlinType, state: TranslationState) : LLVMType() { val types = type.arguments.map { LLVMInstanceOfStandardType("", it.type, state = state) }.toList() returnType = types.last() arguments = types.dropLast(1) + mangle = "F.${LLVMType.mangleFunctionArguments(arguments)}.EF" } - override fun mangle() = - "F.${LLVMType.mangleFunctionArguments(arguments)}.EF" + fun mangleArgs() = LLVMType.mangleFunctionArguments(arguments) - fun mangleArgs(): String = - if (arguments.size > 0) LLVMType.mangleFunctionArguments(arguments) else "" - - override fun toString(): String = + override fun toString() = "${returnType.type} (${arguments.map { it.getType() }.joinToString()})" - override val typename = "FunctionType" + override fun equals(other: Any?) = + (other is LLVMFunctionType) && (mangle == other.mangle) override fun hashCode() = - mangle().hashCode() + mangle.hashCode() - override fun equals(other: Any?): Boolean { - return (other is LLVMFunctionType) && (mangle() == other.mangle()) - } - -} +} \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt index f652888fea5..92d22366cc9 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt @@ -7,87 +7,83 @@ import org.kotlinnative.translator.llvm.LLVMSingleValue class LLVMIntType() : LLVMType() { - override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "or i32 $firstOp, $secondOp") - - override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "and i32 $firstOp, $secondOp") - - override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "xor i32 $firstOp, $secondOp") - - override fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "shl i32 $firstOp, $secondOp") - - override fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "ashr i32 $firstOp, $secondOp") - - override fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "lshr i32 $firstOp, $secondOp") - - //TODO switch by types: int + double = int - override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, $secondOp") - - //TODO switch by types: int + double = int - override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "mul nsw i32 $firstOp, $secondOp") - - //TODO switch by types: int + double = int - override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp") - - override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "sdiv i32 $firstOp, $secondOp") - - override fun operatorInc(firstOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, 1") - - override fun operatorDec(firstOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, 1") - - override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp slt i32 $firstOp, $secondOp") - - override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sgt i32 $firstOp, $secondOp") - - override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sle i32 $firstOp, $secondOp") - - override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sge i32 $firstOp, $secondOp") - - override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp eq i32" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - - override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp ne i32" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - - override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMIntType(), "srem i32 $firstOp, $secondOp") - - override fun equals(other: Any?): Boolean { - return other is LLVMIntType - } - - override fun convertFrom(source: LLVMSingleValue): LLVMExpression = when (source.type!!) { - is LLVMBooleanType, - is LLVMByteType, - is LLVMCharType, - is LLVMShortType -> LLVMExpression(LLVMBooleanType(), " sext ${source.type} $source to i32") - else -> throw UnimplementedException() - } - - override fun mangle() = "Int" - override val align = 4 override var size: Int = 4 override val defaultValue = "0" - + override val mangle = "Int" override val typename = "i32" - override fun isPrimitive() = true + override val isPrimitive = true + + override fun convertFrom(source: LLVMSingleValue) = + when (source.type!!) { + is LLVMBooleanType, + is LLVMByteType, + is LLVMCharType, + is LLVMShortType -> LLVMExpression(LLVMBooleanType(), " sext ${source.type} $source to i32") + else -> throw UnimplementedException() + } + + override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "or i32 $firstOp, $secondOp") + + override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "and i32 $firstOp, $secondOp") + + override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "xor i32 $firstOp, $secondOp") + + override fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "shl i32 $firstOp, $secondOp") + + override fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "ashr i32 $firstOp, $secondOp") + + override fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "lshr i32 $firstOp, $secondOp") + + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, $secondOp") + + override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "mul nsw i32 $firstOp, $secondOp") + + override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "sdiv i32 $firstOp, $secondOp") + + override fun operatorInc(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, 1") + + override fun operatorDec(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, 1") + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i32 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i32 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i32 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i32 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i32" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i32" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "srem i32 $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMIntType + override fun hashCode() = - mangle().hashCode() + mangle.hashCode() } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMLongType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMLongType.kt index 3a2cfe3d860..bbac94c634d 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMLongType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMLongType.kt @@ -7,81 +7,78 @@ import org.kotlinnative.translator.llvm.LLVMSingleValue class LLVMLongType() : LLVMType() { - override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override val align = 8 + override var size = 8 + override val defaultValue = "0" + override val typename = "i64" + override val mangle = "Long" + override val isPrimitive = true + + override fun convertFrom(source: LLVMSingleValue) = + when (source.type!!) { + is LLVMBooleanType, + is LLVMByteType, + is LLVMCharType, + is LLVMShortType, + is LLVMIntType -> LLVMExpression(LLVMBooleanType(), " sext ${source.type} $source to i64") + else -> throw UnimplementedException() + } + + override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "or i64 $firstOp, $secondOp") - override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "and i64 $firstOp, $secondOp") - override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "xor i64 $firstOp, $secondOp") - override fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "shl i64 $firstOp, $secondOp") - override fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "ashr i64 $firstOp, $secondOp") - override fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "lshr i64 $firstOp, $secondOp") - //TODO switch by types: int + double = int - override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "sub nsw i64 $firstOp, $secondOp") - //TODO switch by types: int + double = int - override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "mul nsw i64 $firstOp, $secondOp") - //TODO switch by types: int + double = int - override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "add nsw i64 $firstOp, $secondOp") - override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "sdiv i64 $firstOp, $secondOp") - override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMBooleanType(), "icmp slt i64 $firstOp, $secondOp") - override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMBooleanType(), "icmp sgt i64 $firstOp, $secondOp") - override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMBooleanType(), "icmp sle i64 $firstOp, $secondOp") - override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMBooleanType(), "icmp sge i64 $firstOp, $secondOp") - override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMBooleanType(), "icmp eq i64" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMBooleanType(), "icmp ne i64" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = LLVMExpression(LLVMLongType(), "srem i64 $firstOp, $secondOp") - override fun convertFrom(source: LLVMSingleValue): LLVMExpression = when (source.type!!) { - is LLVMBooleanType, - is LLVMByteType, - is LLVMCharType, - is LLVMShortType, - is LLVMIntType -> LLVMExpression(LLVMBooleanType(), " sext ${source.type} $source to i64") - else -> throw UnimplementedException() - } + override fun equals(other: Any?) = + other is LLVMLongType - override fun equals(other: Any?): Boolean { - return other is LLVMLongType - } - - override val align = 8 - override var size: Int = 8 - override val defaultValue = "0" - - override fun mangle() = "Long" - override val typename = "i64" - override fun isPrimitive() = true override fun hashCode() = - mangle().hashCode() + mangle.hashCode() } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt index 48ad96254e0..db9badcfee4 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt @@ -1,12 +1,13 @@ package org.kotlinnative.translator.llvm.types class LLVMNullType(var baseType: LLVMType? = null) : LLVMType() { + override val align = 1 override var size = 0 override val defaultValue = "null" + override val mangle = "" override val typename = baseType?.typename ?: "" - override fun mangle() = "" override fun parseArg(inputArg: String) = "null" override fun toString() = baseType?.toString() ?: "" diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt index 7b973ea7b0b..79ffa42c7fc 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt @@ -3,6 +3,7 @@ package org.kotlinnative.translator.llvm.types import org.kotlinnative.translator.TranslationState import org.kotlinnative.translator.llvm.LLVMExpression import org.kotlinnative.translator.llvm.LLVMSingleValue +import org.kotlinnative.translator.llvm.addAfterIfNotEmpty import java.util.* class LLVMReferenceType(val type: String, @@ -12,12 +13,10 @@ class LLVMReferenceType(val type: String, var byRef: Boolean = true) : LLVMType() { override val defaultValue: String = "null" - override val typename: String - get() = "$prefix${if (prefix.length > 0) "." else ""}" + - "$type" + override val mangle = "Ref_$type" + override val typename = prefix.addAfterIfNotEmpty(".") + type override fun toString() = "%$typename" - override fun mangle() = "Ref_$type" val location = ArrayList() diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt index 2d0be10a0de..bb4b07167cf 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt @@ -5,42 +5,41 @@ import org.kotlinnative.translator.llvm.LLVMSingleValue class LLVMShortType() : LLVMType() { - override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp slt i16 $firstOp, $secondOp") - - override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sgt i16 $firstOp, $secondOp") - - override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sle i16 $firstOp, $secondOp") - - override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp sge i16 $firstOp, $secondOp") - - override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp eq i16" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - - override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMBooleanType(), "icmp ne i16" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") - - override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMShortType(), "srem i16 $firstOp, $secondOp") - - override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = - LLVMExpression(LLVMShortType(), "sdiv i16 $firstOp, $secondOp") - - override var size: Int = 2 override val align = 2 + override var size: Int = 2 override val defaultValue = "0" override val typename = "i16" + override val mangle = "Short" + override val isPrimitive = true - override fun mangle() = "Short" - override fun isPrimitive() = true + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i16 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i16 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i16 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i16 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i16" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i16" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMShortType(), "srem i16 $firstOp, $secondOp") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMShortType(), "sdiv i16 $firstOp, $secondOp") override fun equals(other: Any?) = other is LLVMShortType override fun hashCode() = - mangle().hashCode() + mangle.hashCode() } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMStringType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMStringType.kt index d155eddbba0..463429c9249 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMStringType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMStringType.kt @@ -2,14 +2,13 @@ package org.kotlinnative.translator.llvm.types class LLVMStringType(override val length: Int, var isLoaded: Boolean = true) : LLVMArray, LLVMType() { - override var size: Int = 1 override val align = 8 + override var size: Int = 1 override val defaultValue = "" override val typename = "i8*" - - override fun mangle() = "String" - override fun basicType() = LLVMCharType() - override fun fullType() = "[${length + 1} x i8]" + override val mangle = "String" + override val arrayElementType = LLVMCharType() + override val fullArrayType = "[${length + 1} x i8]" override fun equals(other: Any?) = when (other) { @@ -19,6 +18,6 @@ class LLVMStringType(override val length: Int, var isLoaded: Boolean = true) : L override fun hashCode() = length * 31 + if (isLoaded) 1 else 0 + - mangle().hashCode() + mangle.hashCode() } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt index e67226e1567..8da7aaf015c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt @@ -6,6 +6,32 @@ import org.kotlinnative.translator.llvm.LLVMSingleValue abstract class LLVMType() : Cloneable { + companion object { + fun mangleFunctionArguments(names: List) = + mangleFunctionTypes(names.map { it.type!! }) + + fun mangleFunctionTypes(names: List) = + if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.mangle })}" else "" + + fun nullOrVoidType(type: LLVMType): Boolean = + (type is LLVMNullType) or (type is LLVMVoidType) + + fun isReferredType(type: LLVMType?): Boolean = + (type is LLVMNullType) or (type is LLVMReferenceType) + + } + + abstract val align: Int + abstract val typename: String + abstract var size: Int + abstract val defaultValue: String + abstract val mangle: String + open val isPrimitive: Boolean = false + + open fun parseArg(inputArg: String) = inputArg + open fun convertFrom(source: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + override fun toString() = typename + open fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() open fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() open fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() @@ -26,29 +52,4 @@ abstract class LLVMType() : Cloneable { open fun operatorInc(firstOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() open fun operatorDec(firstOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() - open fun parseArg(inputArg: String) = inputArg - open fun convertFrom(source: LLVMSingleValue): LLVMExpression = throw UnimplementedException() - open fun mangle(): String = throw UnimplementedException() - open fun isPrimitive(): Boolean = false - override fun toString() = typename - - abstract val align: Int - abstract val typename: String - abstract var size: Int - abstract val defaultValue: String - - companion object { - fun mangleFunctionArguments(names: List) = - mangleFunctionTypes(names.map { it.type!! }) - - fun mangleFunctionTypes(names: List) = - if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.mangle() })}" else "" - - fun nullOrVoidType(type: LLVMType): Boolean = - (type is LLVMNullType) or (type is LLVMVoidType) - - fun isReferredType(type: LLVMType?): Boolean = - (type is LLVMNullType) or (type is LLVMReferenceType) - } - } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt index 4097b1cf985..74d7359ad53 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt @@ -6,8 +6,7 @@ class LLVMVoidType() : LLVMType() { override var size = 0 override val defaultValue = "" override val typename = "void" - - override fun mangle() = "" + override val mangle = "" override fun equals(other: Any?) = other is LLVMVoidType