discovered crash related to float typecasting in asm assignment codegen

This commit is contained in:
Irmen de Jong 2021-11-09 03:45:07 +01:00
parent f2c440e466
commit 7780d94de1
6 changed files with 70 additions and 27 deletions

View File

@ -44,6 +44,8 @@ fun compileProgram(filepath: Path,
lateinit var program: Program lateinit var program: Program
lateinit var importedFiles: List<Path> lateinit var importedFiles: List<Path>
val optimizeFloatExpr = if(optimize) optimizeFloatExpressions else false
val compTarget = val compTarget =
when(compilationTarget) { when(compilationTarget) {
C64Target.name -> C64Target C64Target.name -> C64Target
@ -58,7 +60,7 @@ fun compileProgram(filepath: Path,
with(compilationOptions) { with(compilationOptions) {
this.slowCodegenWarnings = slowCodegenWarnings this.slowCodegenWarnings = slowCodegenWarnings
this.optimize = optimize this.optimize = optimize
this.optimizeFloatExpressions = optimizeFloatExpressions this.optimizeFloatExpressions = optimizeFloatExpr
} }
program = programresult program = programresult
importedFiles = imported importedFiles = imported

View File

@ -23,7 +23,7 @@ private val examplesDir = assumeDirectory(workingDir, "../examples")
private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilationTarget) = compileProgram( private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilationTarget) = compileProgram(
filepath, filepath,
optimize, optimize,
optimizeFloatExpressions = false, optimizeFloatExpressions = true,
writeAssembly = true, writeAssembly = true,
slowCodegenWarnings = false, slowCodegenWarnings = false,
quietAssembler = true, quietAssembler = true,

View File

@ -15,16 +15,14 @@ import prog8.ast.expressions.*
import prog8.ast.statements.* import prog8.ast.statements.*
import prog8.compiler.BeforeAsmGenerationAstChanger import prog8.compiler.BeforeAsmGenerationAstChanger
import prog8.compiler.target.C64Target import prog8.compiler.target.C64Target
import prog8.compiler.target.c64.C64MachineDefinition
import prog8.compiler.target.cpu6502.codegen.AsmGen
import prog8.compilerinterface.* import prog8.compilerinterface.*
import prog8tests.ast.helpers.outputDir
import prog8tests.helpers.DummyFunctions import prog8tests.helpers.DummyFunctions
import prog8tests.helpers.DummyMemsizer import prog8tests.helpers.DummyMemsizer
import prog8tests.helpers.DummyStringEncoder import prog8tests.helpers.DummyStringEncoder
import prog8tests.helpers.ErrorReporterForTests import prog8tests.helpers.ErrorReporterForTests
import prog8tests.helpers.assertSuccess import prog8tests.helpers.assertSuccess
import prog8tests.helpers.compileText import prog8tests.helpers.compileText
import prog8tests.helpers.generateAssembly
class TestOptimization: FunSpec({ class TestOptimization: FunSpec({
test("testRemoveEmptySubroutineExceptStart") { test("testRemoveEmptySubroutineExceptStart") {
@ -188,10 +186,34 @@ class TestOptimization: FunSpec({
(bbAssigns1expr.right as PrefixExpression).expression shouldBe IdentifierReference(listOf("ww"), Position.DUMMY) (bbAssigns1expr.right as PrefixExpression).expression shouldBe IdentifierReference(listOf("ww"), Position.DUMMY)
bbAssigns1expr.inferType(result.program).getOrElse { fail("dt") } shouldBe DataType.UBYTE bbAssigns1expr.inferType(result.program).getOrElse { fail("dt") } shouldBe DataType.UBYTE
val zp = C64MachineDefinition.C64Zeropage(options) val asm = generateAssembly(result.program, options)
options.compTarget.machine.zeropage=zp asm.valid shouldBe true
val asmgen = AsmGen(result.program, ErrorReporterForTests(), zp, options, C64Target, outputDir) }
val asm = asmgen.compileToAssembly()
test("asmgen correctly deals with float typecasting in augmented assignment") {
val src="""
%option enable_floats
main {
sub start() {
ubyte ub
float ff
ff += (ub as float) ; operator doesn't matter
}
}
"""
val result1 = compileText(C64Target, optimize=false, src, writeAssembly = false).assertSuccess()
// yy = (dy*(pixely as float) )
val assignYY = result1.program.entrypoint.statements.last() as Assignment
assignYY.isAugmentable shouldBe true
assignYY.target.identifier!!.nameInSource shouldBe listOf("ff")
val value = assignYY.value as BinaryExpression
value.operator shouldBe "+"
value.left shouldBe IdentifierReference(listOf("ff"), Position.DUMMY)
value.right shouldBe instanceOf<TypecastExpression>()
val asm = generateAssembly(result1.program)
asm.valid shouldBe true asm.valid shouldBe true
} }
}) })

View File

@ -2,10 +2,13 @@ package prog8tests.helpers
import io.kotest.assertions.withClue import io.kotest.assertions.withClue
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import prog8.ast.Program
import prog8.compiler.CompilationResult import prog8.compiler.CompilationResult
import prog8.compiler.compileProgram import prog8.compiler.compileProgram
import prog8.compilerinterface.ICompilationTarget import prog8.compiler.target.C64Target
import prog8.compilerinterface.IErrorReporter import prog8.compiler.target.c64.C64MachineDefinition
import prog8.compiler.target.cpu6502.codegen.AsmGen
import prog8.compilerinterface.*
import prog8tests.ast.helpers.assumeReadableFile import prog8tests.ast.helpers.assumeReadableFile
import prog8tests.ast.helpers.outputDir import prog8tests.ast.helpers.outputDir
import java.nio.file.Path import java.nio.file.Path
@ -37,14 +40,15 @@ internal fun compileFile(
fileName: String, fileName: String,
outputDir: Path = prog8tests.ast.helpers.outputDir, outputDir: Path = prog8tests.ast.helpers.outputDir,
errors: IErrorReporter? = null, errors: IErrorReporter? = null,
writeAssembly: Boolean = true writeAssembly: Boolean = true,
optFloatExpr: Boolean = true
) : CompilationResult { ) : CompilationResult {
val filepath = fileDir.resolve(fileName) val filepath = fileDir.resolve(fileName)
assumeReadableFile(filepath) assumeReadableFile(filepath)
return compileProgram( return compileProgram(
filepath, filepath,
optimize, optimize,
optimizeFloatExpressions = false, optimizeFloatExpressions = optFloatExpr,
writeAssembly = writeAssembly, writeAssembly = writeAssembly,
slowCodegenWarnings = false, slowCodegenWarnings = false,
quietAssembler = true, quietAssembler = true,
@ -65,10 +69,23 @@ internal fun compileText(
optimize: Boolean, optimize: Boolean,
sourceText: String, sourceText: String,
errors: IErrorReporter? = null, errors: IErrorReporter? = null,
writeAssembly: Boolean = true writeAssembly: Boolean = true,
optFloatExpr: Boolean = true
) : CompilationResult { ) : CompilationResult {
val filePath = outputDir.resolve("on_the_fly_test_" + sourceText.hashCode().toUInt().toString(16) + ".p8") val filePath = outputDir.resolve("on_the_fly_test_" + sourceText.hashCode().toUInt().toString(16) + ".p8")
// we don't assumeNotExists(filePath) - should be ok to just overwrite it // we don't assumeNotExists(filePath) - should be ok to just overwrite it
filePath.toFile().writeText(sourceText) filePath.toFile().writeText(sourceText)
return compileFile(platform, optimize, filePath.parent, filePath.name, errors=errors, writeAssembly=writeAssembly) return compileFile(platform, optimize, filePath.parent, filePath.name, errors=errors, writeAssembly=writeAssembly, optFloatExpr = optFloatExpr)
}
internal fun generateAssembly(
program: Program,
options: CompilationOptions? = null
): IAssemblyProgram {
val coptions = options ?: CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, true, C64Target)
val zp = C64MachineDefinition.C64Zeropage(coptions)
coptions.compTarget.machine.zeropage=zp
val asmgen = AsmGen(program, ErrorReporterForTests(), zp, coptions, C64Target, outputDir)
return asmgen.compileToAssembly()
} }

View File

@ -18,15 +18,15 @@ enum class ZeropageType {
DONTUSE DONTUSE
} }
data class CompilationOptions(val output: OutputType, class CompilationOptions(val output: OutputType,
val launcher: LauncherType, val launcher: LauncherType,
val zeropage: ZeropageType, val zeropage: ZeropageType,
val zpReserved: List<IntRange>, val zpReserved: List<IntRange>,
val floats: Boolean, val floats: Boolean,
val noSysInit: Boolean, val noSysInit: Boolean,
val compTarget: ICompilationTarget val compTarget: ICompilationTarget,
) { // these are set based on command line arguments:
var slowCodegenWarnings = false var slowCodegenWarnings: Boolean = false,
var optimize = false var optimize: Boolean = false,
var optimizeFloatExpressions = false var optimizeFloatExpressions: Boolean = false
} )

View File

@ -3,6 +3,8 @@ TODO
For next compiler release (7.3) For next compiler release (7.3)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- fix float crash in mandelbrot-gfx-colors.p8 (unittest is being written)
- add cosr8, sinr8, cosr16 and sinr16 that take a degree 0..179 (= 0..359 in 2 degree steps) - add cosr8, sinr8, cosr16 and sinr16 that take a degree 0..179 (= 0..359 in 2 degree steps)
to more easily scale halves/quarters etc of a circle than possible with the ones that take 0..255 'degrees'. to more easily scale halves/quarters etc of a circle than possible with the ones that take 0..255 'degrees'.