Skip to content

Commit

Permalink
use gas syntax (don't require nasm)
Browse files Browse the repository at this point in the history
  • Loading branch information
avan1235 committed Jan 31, 2022
1 parent d60a3af commit 6ad627e
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 62 deletions.
5 changes: 3 additions & 2 deletions src/main/kotlin/ml/dev/kotlin/latte/asm/Allocator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ class Allocator(
is LocalValue -> locations[value.id]
is BooleanConstValue -> Imm(if (value.bool) "1" else "0", value.type)
is IntConstValue -> Imm("${value.int}", value.type)
is StringConstValue -> Imm(strings[value.str]?.name ?: err("Used not labeled string $this"), value.type)
is LabelConstValue -> Imm(value.label.name, value.type)
is StringConstValue -> Imm(strings[value.str]?.name?.let { "OFFSET $it" }
?: err("Used not labeled string $this"), value.type)
is LabelConstValue -> Imm("OFFSET ${value.label.name}", value.type)
is NullConstValue -> Imm("0", value.type)
} ?: err("Used not defined variable $value")
}
Expand Down
17 changes: 9 additions & 8 deletions src/main/kotlin/ml/dev/kotlin/latte/asm/Compiler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ private class Compiler(
private val result: StringBuilder = StringBuilder(),
) {
fun IR.compile(): String {
STD_LIB_FUNCTIONS.keys.forEach { result.append("extern ").appendLine(it) }
graph.functions.keys.forEach { result.append("global ").appendLine(it.name) }
result.appendLine(".intel_syntax noprefix")
STD_LIB_FUNCTIONS.keys.forEach { result.append(".extern ").appendLine(it) }
graph.functions.keys.forEach { result.append(".global ").appendLine(it.name) }
val code = compileFunctions()
result.appendLine("section .data")
result.appendLine(".section .data")
strings.defineUsedStrings(code)
vTables.defineVTables()
result.appendLine("section .text")
result.appendLine(".section .text")
result.appendLine(code)
return result.toString()
}
Expand All @@ -34,7 +35,7 @@ private class Compiler(
private fun Map<String, Label>.defineUsedStrings(code: String) {
entries.forEach { (string, label) ->
if (!label.name.toRegex().containsMatchIn(code)) return@forEach
result.append(label.name).append(": db ")
result.append(label.name).append(": .byte ")
val bytes = string.toByteArray()
bytes.joinTo(result, separator = ", ")
if (bytes.isNotEmpty()) result.appendLine(", 0") else result.appendLine("0")
Expand All @@ -44,8 +45,8 @@ private class Compiler(
private fun Map<Type, VirtualTable>.defineVTables() {
entries.forEach { (classType, vTable) ->
if (vTable.declarations.isEmpty()) return@forEach
result.append(classType.typeName).append(": dd ")
vTable.declarations.joinTo(result, separator = ", ") { it.name }
result.append(classType.typeName).append(": .long ")
vTable.declarations.joinTo(result, prefix = "OFFSET ", separator = ", OFFSET ") { it.name }
result.appendLine()
}
}
Expand All @@ -57,6 +58,6 @@ val CLASS_METHOD_ARGS_OFFSET: Bytes = VoidRefType.size
const val THIS_ARG_ID: String = "self"
val ALLOC_FUN_LABEL: Label = "__alloc".label
val CONCAT_STRING_FUN_LABEL: Label = "__concatString".label
val EMPTY_STRING_LABEL: Label = "S@EMPTY".label
val EMPTY_STRING_LABEL: Label = "EMPTY".label


3 changes: 1 addition & 2 deletions src/main/kotlin/ml/dev/kotlin/latte/asm/Nasm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import java.nio.file.Files
fun nasm(assembly: File, libFile: File = DEFAULT_LIB_FILE): CompilationResult {
val o = assembly.withExtension(".o")
val result = assembly.withExtension("")
listOf("nasm", "-f", "elf32", assembly.absolutePath, "-o", o.absolutePath).run()
withLibFile(libFile) { lib ->
listOf("gcc", "-m32", "-static", lib.absolutePath, o.absolutePath, "-o", result.absolutePath).run()
listOf("gcc", "-m32", "-static", lib.absolutePath, assembly.absolutePath, "-o", result.absolutePath).run()
}
return CompilationResult(o, result)
}
Expand Down
13 changes: 7 additions & 6 deletions src/main/kotlin/ml/dev/kotlin/latte/asm/VarLoc.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ml.dev.kotlin.latte.asm
import ml.dev.kotlin.latte.asm.Reg.EBP
import ml.dev.kotlin.latte.quadruple.Named
import ml.dev.kotlin.latte.syntax.Bytes
import ml.dev.kotlin.latte.syntax.PrimitiveType.VoidRefType
import ml.dev.kotlin.latte.syntax.Type
import ml.dev.kotlin.latte.util.LatteIllegalStateException
import ml.dev.kotlin.latte.util.msg
Expand All @@ -11,22 +12,22 @@ sealed interface VarLoc : Named
sealed interface Mem : VarLoc

data class Imm(private val value: String, private val type: Type) : VarLoc {
override val name = "${type.wordSize} $value"
override val name = value
}

data class Arg(private val offset: Bytes, private val type: Type) : Mem {
override val name = "${type.wordSize} [$EBP + ${ARG_OFFSET + offset}]"
override val name = "${type.wordSize} PTR [$EBP + ${ARG_OFFSET + offset}]"
}

data class Loc(private val offset: Bytes, private val type: Type) : Mem {
override val name = "${type.wordSize} [$EBP - ${LOCAL_OFFSET + offset}]"
override val name = "${type.wordSize} PTR [$EBP - ${LOCAL_OFFSET + offset}]"
}

data class Adr(val loc: Reg, val offset: Bytes = 0) : Named {
override val name: String = when {
offset > 0 -> "[${loc.name} + $offset]"
offset < 0 -> "[${loc.name} - ${-offset}]"
else -> "[${loc.name}]"
offset > 0 -> "${VoidRefType.wordSize} PTR [${loc.name} + $offset]"
offset < 0 -> "${VoidRefType.wordSize} PTR [${loc.name} - ${-offset}]"
else -> "${VoidRefType.wordSize} PTR [${loc.name}]"
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/ml/dev/kotlin/latte/syntax/Type.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ enum class PrimitiveType(override val typeName: String, override val size: Bytes
IntType("int", 4),
StringType("string", 4),
BooleanType("boolean", 4),
VoidRefType("void~", 4),
VoidRefType("voidRef", 4),
VoidType("void", 4) {
override val size: Bytes get() = throw LatteIllegalStateException("Cannot get size of $this type".msg)
};
Expand All @@ -27,7 +27,7 @@ enum class PrimitiveType(override val typeName: String, override val size: Bytes

class RefType(override val typeName: String, override val span: Span? = null) : Type {
override val size: Bytes = 4
override fun toString(): String = "$typeName~"
override fun toString(): String = "${typeName}Ref"
override fun hashCode(): Int = typeName.hashCode()
override fun equals(other: Any?): Boolean = (other as? RefType)?.typeName == typeName
}
4 changes: 3 additions & 1 deletion src/main/kotlin/ml/dev/kotlin/latte/typecheck/TypeUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ fun createStdLibFunEnv(): LinkedHashMap<FunSignature, FunDeclaration> = STD_LIB.
}

infix fun String.mangled(args: List<Type>): String =
if (this with args in STD_LIB_FUNCTIONS_SIGNATURES) "__$this" else "$this${args.joinToString("") { "@$it" }}"
if (this with args in STD_LIB_FUNCTIONS_SIGNATURES) "__$this" else "$this${args.joinToString("") { "$ARG_SEP$it" }}"

const val ARG_SEP: String = "$$"

data class FunSignature(val name: String, val args: List<Type>)
data class FunDeclaration(val name: String, val args: List<Type>, val ret: Type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ private fun testCompilerWithAllocatorStrategy(
val programFile = Files.createTempFile(dataDir, shortcut, ".lat").toFile().apply { writeText(program) }
val inputFile = input?.let { programFile.withExtension(".input", it.trimIndent()) }
val compiled = programFile.runCompiler(strategy = allocator.strategy)
val asmFile = programFile.withExtension(".asm", compiled)
val asmFile = programFile.withExtension(".s", compiled)
val (o, exe) = nasm(asmFile, libFile = File("lib/runtime.o"))
val outFile = programFile.withExtension(".outputTest")
val errFile = programFile.withExtension(".errorTest")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private fun testCompilerWithAllocatorStrategy(
val expected = input.withExtension(".output").readText()
val inputFile = input.withExtension(".input").takeIf { it.exists() }
val compiled = input.runCompiler(strategy = allocator.strategy)
val asmFile = input.withExtension(".${shortcut}.asm").apply { writeText(compiled) }
val asmFile = input.withExtension(".${shortcut}.s").apply { writeText(compiled) }
val (o, exe) = nasm(asmFile, libFile = File("lib/runtime.o"))
val outFile = input.withExtension(".${shortcut}.outputTest").apply { createNewFile() }
val errFile = input.withExtension(".${shortcut}.errorTest").apply { createNewFile() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ private fun configuredRunCompiler(
val programFile = Files.createTempFile(dataDir, "opt", ".lat").toFile().apply { writeText(program) }
val inputFile = input?.let { programFile.withExtension(".input", it.trimIndent()) }
val code = programFile.runCompiler(true, propagateConstants, simplifyExpr, true, lcse, gcse)
val asmFile = programFile.withExtension(".asm", code)
val asmFile = programFile.withExtension(".s", code)
val (o, exe) = nasm(asmFile, libFile = File("lib/runtime.o"))
val outFile = programFile.withExtension(".outputTest")
val errFile = programFile.withExtension(".errorTest")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ml.dev.kotlin.latte.quadruple

import ml.dev.kotlin.latte.syntax.PrimitiveType.IntType
import ml.dev.kotlin.latte.syntax.parse
import ml.dev.kotlin.latte.typecheck.ARG_SEP
import ml.dev.kotlin.latte.typecheck.mangled
import ml.dev.kotlin.latte.typecheck.typeCheck
import ml.dev.kotlin.latte.util.DefaultMap
Expand All @@ -27,7 +28,7 @@ internal class GlobalFlowAnalyzerTest {
}
""",
/**
* 0: f@int(x#0):
* 0: f$$int(x#0):
* 1: ret x#0
*/
label = "f" mangled listOf(IntType),
Expand Down Expand Up @@ -67,7 +68,7 @@ internal class GlobalFlowAnalyzerTest {
}
""",
/**
* 0: f@int(x#0):
* 0: f$$int(x#0):
* 1: y@1#0 = 0
* 2: if x#0 eq 42 goto L2
* 3: y@1#3 = x#0
Expand Down Expand Up @@ -154,7 +155,7 @@ internal class GlobalFlowAnalyzerTest {
}
""",
/**
* 0: f@int(x#0):
* 0: f$$int(x#0):
* 1: y@1#0 = 0
* 2: y@1#1 = y@1#0
* 3: goto L3
Expand Down Expand Up @@ -206,34 +207,34 @@ internal class GlobalFlowAnalyzerTest {
}
""",
/**
* 0: f@int(x#0):
* 0: f$$int(x#0):
* 1: ret x#0
*/
/**
* 0: f@int(x#0):
* 0: f$$int(x#0):
* 1: ret x#0
*/
label = "f" mangled listOf(IntType),
aliveBefore = mapOf(
"f@int".label to mapOf(
"f${ARG_SEP}int".label to mapOf(
0 to setOf(),
1 to setOf(intArg("x#0", 0))
),
),
aliveAfter = mapOf(
"f@int".label to mapOf(
"f${ARG_SEP}int".label to mapOf(
0 to setOf(intArg("x#0", 0)),
1 to setOf(),
)
),
definedAt = mapOf(
"f@int".label to mapOf(
"f${ARG_SEP}int".label to mapOf(
0 to setOf(intArg("x#0", 0)),
1 to setOf(),
)
),
usedAt = mapOf(
"f@int".label to mapOf(
"f${ARG_SEP}int".label to mapOf(
0 to setOf(),
1 to setOf(intArg("x#0", 0)),
)
Expand All @@ -258,7 +259,7 @@ internal class GlobalFlowAnalyzerTest {
}
""",
/**
* 0: f@int(x#0):
* 0: f$$int(x#0):
* 1: y@1#0 = 0
* 2: if x#0 eq 42 goto L2
* 3: G6:
Expand All @@ -276,7 +277,7 @@ internal class GlobalFlowAnalyzerTest {
*/
label = "f" mangled listOf(IntType),
aliveBefore = mapOf(
"f@int".label to mapOf(
"f${ARG_SEP}int".label to mapOf(
0 to setOf(),
1 to setOf(intArg("x#0", 0)),
2 to setOf(intArg("x#0", 0)),
Expand All @@ -303,7 +304,7 @@ internal class GlobalFlowAnalyzerTest {
)
),
aliveAfter = mapOf(
"f@int".label to mapOf(
"f${ARG_SEP}int".label to mapOf(
0 to setOf(intArg("x#0", 0)),
1 to setOf(intArg("x#0", 0)),
2 to setOf(intArg("x#0", 0)),
Expand Down Expand Up @@ -348,7 +349,7 @@ internal class GlobalFlowAnalyzerTest {
}
""",
/**
* 0: f@int(x#0):
* 0: f$$int(x#0):
* 1: y@1#0 = 0
* 2: y@1#1 = y@1#0
* 3: goto L3
Expand All @@ -364,7 +365,7 @@ internal class GlobalFlowAnalyzerTest {
*/
label = "f" mangled listOf(IntType),
aliveBefore = mapOf(
"f@int".label to mapOf(
"f${ARG_SEP}int".label to mapOf(
0 to setOf(),
1 to setOf(intArg("x#0", 0)),
2 to setOf(intArg("x#0", 0), intLoc("y@1#0")),
Expand All @@ -389,7 +390,7 @@ internal class GlobalFlowAnalyzerTest {
),
),
aliveAfter = mapOf(
"f@int".label to mapOf(
"f${ARG_SEP}int".label to mapOf(
0 to setOf(intArg("x#0", 0)),
1 to setOf(intArg("x#0", 0), intLoc("y@1#0")),
2 to setOf(intArg("x#0", 0), intLoc("y@1#1")),
Expand Down
Loading

0 comments on commit 6ad627e

Please sign in to comment.