diff --git a/translator/src/main/kotlin/main.kt b/translator/src/main/kotlin/main.kt index a20153dbc5f..350babc2643 100644 --- a/translator/src/main/kotlin/main.kt +++ b/translator/src/main/kotlin/main.kt @@ -10,7 +10,7 @@ fun main(args: Array) { } val disposer = Disposer.newDisposable() - val state = parseAndAnalyze(args.asList(), disposer) + val state = parseAndAnalyze(args.asList(), disposer, true) val files = state.environment.getSourceFiles() if (files.isEmpty()) { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt index 9e38a2ab109..d7508072056 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt @@ -72,7 +72,7 @@ class ClassCodegen(val state: TranslationState, val clazz: KtClass, val codeBuil argFields.add(thisField) argFields.addAll(fields) - codeBuilder.addLLVMCode(LLVMFunctionDescriptor(clazz.name!!, argFields, LLVMVoidType())) + codeBuilder.addLLVMCode(LLVMFunctionDescriptor(clazz.name!!, argFields, LLVMVoidType(), arm = state.arm)) codeBuilder.addStartExpression() generateLoadArguments(thisField) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt index 52eb5f7f65c..c4a940c732e 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt @@ -7,7 +7,7 @@ import org.kotlinnative.translator.llvm.LLVMBuilder class FileTranslator(val state: TranslationState, val file: KtFile) { - private var codeBuilder = LLVMBuilder() + private var codeBuilder = LLVMBuilder(state.arm) fun generateCode(): String { codeBuilder.clean() diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index fface322c0a..8742483843c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -60,7 +60,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction keyword = keyword.getNextSiblingIgnoringWhitespaceAndComments() } - codeBuilder.addLLVMCode(LLVMFunctionDescriptor(function.fqName.toString(), args, returnType, external)) + codeBuilder.addLLVMCode(LLVMFunctionDescriptor(function.fqName.toString(), args, returnType, external, state.arm)) return external } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt index d1445bb0788..c0e26f3969c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -20,14 +20,14 @@ import org.jetbrains.kotlin.utils.PathUtil import org.kotlinnative.translator.exceptions.TranslationException import java.util.* -class TranslationState(val environment: KotlinCoreEnvironment, val bindingContext: BindingContext) { +class TranslationState(val environment: KotlinCoreEnvironment, val bindingContext: BindingContext, val arm: Boolean) { var functions = HashMap() var classes = HashMap() val variableManager = VariableManager() } -fun parseAndAnalyze(sources: List, disposer: Disposable): TranslationState { +fun parseAndAnalyze(sources: List, disposer: Disposable, arm: Boolean = false): TranslationState { val configuration = CompilerConfiguration() val messageCollector = GroupingMessageCollector(object : MessageCollector { @@ -49,7 +49,7 @@ fun parseAndAnalyze(sources: List, disposer: Disposable): TranslationSta val environment = KotlinCoreEnvironment.createForProduction(disposer, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) val bindingContext = analyze(environment)?.bindingContext ?: throw TranslationException() - return TranslationState(environment, bindingContext) + return TranslationState(environment, bindingContext, arm) } fun analyze(environment: KotlinCoreEnvironment): AnalysisResult? { 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 eea1407dfa2..60d52c2a6b0 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -5,7 +5,7 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.kotlinnative.translator.llvm.types.LLVMIntType import org.kotlinnative.translator.llvm.types.LLVMType -class LLVMBuilder { +class LLVMBuilder(val arm: Boolean) { private var llvmCode: StringBuilder = StringBuilder() private var variableCount = 0 private var labelCount = 0 @@ -16,7 +16,12 @@ class LLVMBuilder { private fun initBuilder() { val memcpy = "declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)" + val funcAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }""" llvmCode.appendln(memcpy) + + if (arm) { + llvmCode.appendln(funcAttributes) + } } fun getNewVariable(type: LLVMType?, pointer: Boolean = false, kotlinName: String? = null): LLVMVariable { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt index 880ff852898..236e6cf2928 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -3,11 +3,11 @@ package org.kotlinnative.translator.llvm import org.kotlinnative.translator.llvm.types.* -fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnType: LLVMType, declare: Boolean = false) = +fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnType: LLVMType, declare: Boolean = false, arm: Boolean = false) = "${if (declare) "declare" else "define"} $returnType @$name(${ argTypes?.mapIndexed { i: Int, s: LLVMVariable -> "${s.getType()} %${s.label}" - }?.joinToString()})" + }?.joinToString() }) ${ if (arm) "#0 " else ""}" fun LLVMMapStandardType(type: String): LLVMType = when (type) { "Int" -> LLVMIntType()