float eval result var added, but some examples are broken

This commit is contained in:
Irmen de Jong 2020-11-08 18:54:02 +01:00
parent 6eb9118197
commit 4cd74daf53
9 changed files with 70 additions and 52 deletions

View File

@ -57,19 +57,11 @@ interface IFunctionCall {
}
class AsmGenInfo {
var usedAutoArrayIndexerForStatements = mutableMapOf<String, MutableSet<Statement>>()
var usedRegsaveA = false
var usedRegsaveX = false
var usedRegsaveY = false
}
interface INameScope {
val name: String
val position: Position
val statements: MutableList<Statement>
val parent: Node
val asmGenInfo: AsmGenInfo
fun linkParents(parent: Node)
@ -288,7 +280,6 @@ class Module(override val name: String,
override lateinit var parent: Node
lateinit var program: Program
override val asmGenInfo = AsmGenInfo()
val importedBy = mutableListOf<Module>()
val imports = mutableSetOf<Module>()
@ -322,7 +313,6 @@ class GlobalNamespace(val modules: List<Module>): Node, INameScope {
override val position = Position("<<<global>>>", 0, 0, 0)
override val statements = mutableListOf<Statement>() // not used
override var parent: Node = ParentSentinel
override val asmGenInfo = AsmGenInfo()
override fun linkParents(parent: Node) {
modules.forEach { it.linkParents(this) }
@ -375,7 +365,6 @@ object BuiltinFunctionScopePlaceholder : INameScope {
override val position = Position("<<placeholder>>", 0, 0, 0)
override var statements = mutableListOf<Statement>()
override var parent: Node = ParentSentinel
override val asmGenInfo = AsmGenInfo()
override fun linkParents(parent: Node) {}
}

View File

@ -52,7 +52,6 @@ class Block(override val name: String,
val isInLibrary: Boolean,
override val position: Position) : Statement(), INameScope {
override lateinit var parent: Node
override val asmGenInfo = AsmGenInfo()
override fun linkParents(parent: Node) {
this.parent = parent
@ -642,7 +641,6 @@ class AnonymousScope(override var statements: MutableList<Statement>,
override val position: Position) : INameScope, Statement() {
override val name: String
override lateinit var parent: Node
override val asmGenInfo = AsmGenInfo()
companion object {
private var sequenceNumber = 1
@ -681,6 +679,18 @@ class NopStatement(override val position: Position): Statement() {
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
}
class AsmGenInfo {
// This class contains various attributes that influence the assembly code generator.
// Conceptually it should be part of any INameScope.
// But because the resulting code only creates "real" scopes on a subroutine level,
// it's more consistent to only define these attributes on a Subroutine node.
var usedAutoArrayIndexerForStatements = mutableMapOf<String, MutableSet<Statement>>()
var usedRegsaveA = false
var usedRegsaveX = false
var usedRegsaveY = false
var usedFloatEvalResultVar = false
}
// the subroutine class covers both the normal user-defined subroutines,
// and also the predefined/ROM/register-based subroutines.
// (multiple return types can only occur for the latter type)
@ -712,7 +722,7 @@ class Subroutine(override val name: String,
}
override lateinit var parent: Node
override val asmGenInfo = AsmGenInfo()
val asmGenInfo = AsmGenInfo()
val scopedname: String by lazy { makeScopedName(name) }
override fun linkParents(parent: Node) {
@ -996,7 +1006,6 @@ class StructDecl(override val name: String,
override val position: Position): Statement(), INameScope {
override lateinit var parent: Node
override val asmGenInfo = AsmGenInfo()
override fun linkParents(parent: Node) {
this.parent = parent

View File

@ -796,6 +796,8 @@ internal class AsmGen(private val program: Program,
out("_prog8_regsaveX .byte 0")
if(sub.asmGenInfo.usedRegsaveY)
out("_prog8_regsaveY .byte 0")
if(sub.asmGenInfo.usedFloatEvalResultVar)
out("_prog8_float_eval_result .byte 0,0,0,0,0")
vardecls2asm(sub.statements)
out(" .pend\n")
}
@ -1179,7 +1181,7 @@ $counterVar .byte 0""")
out(" lda #<${asmVar} | ldy #>${asmVar} | jsr floats.MOVFM")
}
else -> {
// todo evaluate into fac1 instead of stack
// todo evaluate directly into fac1 instead of stack
translateExpression(returnvalue)
out(" jsr floats.pop_float_fac1")
}

View File

@ -8,6 +8,7 @@ import prog8.ast.expressions.*
import prog8.ast.statements.ArrayIndex
import prog8.ast.statements.DirectMemoryWrite
import prog8.ast.statements.FunctionCallStatement
import prog8.ast.statements.Subroutine
import prog8.compiler.AssemblyError
import prog8.compiler.target.CompilationTarget
import prog8.compiler.target.Cx16Target
@ -36,24 +37,25 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
if(discardResult && resultToStack)
throw AssemblyError("cannot both discard the result AND put it onto stack")
val scope = (fcall as Node).definingSubroutine()!!
when (func.name) {
"msb" -> funcMsb(fcall, resultToStack)
"lsb" -> funcLsb(fcall, resultToStack)
"mkword" -> funcMkword(fcall, resultToStack)
"abs" -> funcAbs(fcall, func, resultToStack)
"abs" -> funcAbs(fcall, func, resultToStack, scope)
"swap" -> funcSwap(fcall)
"min", "max" -> funcMinMax(fcall, func, resultToStack)
"sum" -> funcSum(fcall, resultToStack)
"any", "all" -> funcAnyAll(fcall, func, resultToStack)
"sin8", "sin8u", "sin16", "sin16u",
"cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, resultToStack)
"sgn" -> funcSgn(fcall, func, resultToStack)
"cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, resultToStack, scope)
"sgn" -> funcSgn(fcall, func, resultToStack, scope)
"sin", "cos", "tan", "atan",
"ln", "log2", "sqrt", "rad",
"deg", "round", "floor", "ceil",
"rndf" -> funcVariousFloatFuncs(fcall, func, resultToStack)
"rndf" -> funcVariousFloatFuncs(fcall, func, resultToStack, scope)
"rnd", "rndw" -> funcRnd(func, resultToStack)
"sqrt16" -> funcSqrt16(fcall, func, resultToStack)
"sqrt16" -> funcSqrt16(fcall, func, resultToStack, scope)
"rol" -> funcRol(fcall)
"rol2" -> funcRol2(fcall)
"ror" -> funcRor(fcall)
@ -80,21 +82,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
"clear_irqd" -> asmgen.out(" cli")
"set_irqd" -> asmgen.out(" sei")
"strlen" -> funcStrlen(fcall, resultToStack)
"strcmp" -> funcStrcmp(fcall, func, resultToStack)
"memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func)
"strcmp" -> funcStrcmp(fcall, func, resultToStack, scope)
"memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, scope)
"substr", "leftstr", "rightstr" -> {
translateArguments(fcall.args, func)
translateArguments(fcall.args, func, scope)
asmgen.out(" jsr prog8_lib.func_${func.name}")
}
"exit" -> {
translateArguments(fcall.args, func)
translateArguments(fcall.args, func, scope)
asmgen.out(" jmp prog8_lib.func_exit")
}
else -> TODO("missing asmgen for builtin func ${func.name}")
}
}
private fun funcMemSetCopy(fcall: IFunctionCall, func: FSignature) {
private fun funcMemSetCopy(fcall: IFunctionCall, func: FSignature, scope: Subroutine) {
if(CompilationTarget.instance is Cx16Target) {
when(func.name) {
"memset" -> {
@ -121,7 +123,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
val countDt = fcall.args[2].inferType(program)
if((count!=null && count <= 255) || countDt.istype(DataType.UBYTE) || countDt.istype(DataType.BYTE)) {
// fast memcopy of up to 255
translateArguments(fcall.args, func)
translateArguments(fcall.args, func, scope)
asmgen.out(" jsr prog8_lib.func_memcopy255")
return
}
@ -145,7 +147,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
asmgen.restoreRegister(CpuRegister.X, false)
}
"memsetw" -> {
translateArguments(fcall.args, func)
translateArguments(fcall.args, func, scope)
asmgen.out(" jsr prog8_lib.func_memsetw")
}
}
@ -154,34 +156,34 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
val count = fcall.args[2].constValue(program)?.number?.toInt()
val countDt = fcall.args[2].inferType(program)
if((count!=null && count <= 255) || countDt.istype(DataType.UBYTE) || countDt.istype(DataType.BYTE)) {
translateArguments(fcall.args, func)
translateArguments(fcall.args, func, scope)
asmgen.out(" jsr prog8_lib.func_memcopy255")
return
}
}
translateArguments(fcall.args, func)
translateArguments(fcall.args, func, scope)
asmgen.out(" jsr prog8_lib.func_${func.name}")
}
}
private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
translateArguments(fcall.args, func)
private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
translateArguments(fcall.args, func, scope)
if(resultToStack)
asmgen.out(" jsr prog8_lib.func_strcmp_stack")
else
asmgen.out(" jsr prog8_lib.func_strcmp")
}
private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
translateArguments(fcall.args, func)
private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
translateArguments(fcall.args, func, scope)
if(resultToStack)
asmgen.out(" jsr prog8_lib.func_sqrt16_stack")
else
asmgen.out(" jsr prog8_lib.func_sqrt16_into_A")
}
private fun funcSinCosInt(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
translateArguments(fcall.args, func)
private fun funcSinCosInt(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
translateArguments(fcall.args, func, scope)
if(resultToStack)
asmgen.out(" jsr prog8_lib.func_${func.name}_stack")
else
@ -458,16 +460,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
asmgen.translateNormalAssignment(assign)
}
private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
translateArguments(fcall.args, func)
private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
translateArguments(fcall.args, func, scope)
if(resultToStack)
asmgen.out(" jsr floats.func_${func.name}_stack")
else
asmgen.out(" jsr floats.func_${func.name}_fac1")
}
private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
translateArguments(fcall.args, func)
private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
translateArguments(fcall.args, func, scope)
val dt = fcall.args.single().inferType(program)
if(resultToStack) {
when (dt.typeOrElse(DataType.STRUCT)) {
@ -930,8 +932,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
}
}
private fun funcAbs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
translateArguments(fcall.args, func)
private fun funcAbs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
translateArguments(fcall.args, func, scope)
val dt = fcall.args.single().inferType(program).typeOrElse(DataType.STRUCT)
if(resultToStack) {
when (dt) {
@ -1040,7 +1042,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
""")
}
private fun translateArguments(args: MutableList<Expression>, signature: FSignature) {
private fun translateArguments(args: MutableList<Expression>, signature: FSignature, scope: Subroutine) {
val callConv = signature.callConvention(args.map { it.inferType(program).typeOrElse(DataType.STRUCT) })
fun getSourceForFloat(value: Expression): AsmAssignSource {
@ -1053,15 +1055,15 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
throw AssemblyError("float literals should have been converted into autovar")
}
else -> {
TODO("evaluate float expression, store float in (to be defined) result variable, get address of that variable.")
// val variable = IdentifierReference(listOf("p8_float_eval_result"), value.position)
// variable.linkParents(value)
// val assign = AsmAssignment(AsmAssignSource.fromAstSource(value, program, asmgen),
// AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.FLOAT, null, variableAsmName = asmgen.asmVariableName(variable)),
// false, Position.DUMMY)
// asmgen.translateNormalAssignment(assign)
// val addr = AddressOf(variable, value.position)
// AsmAssignSource.fromAstSource(addr, program, asmgen)
scope.asmGenInfo.usedFloatEvalResultVar = true
val variable = IdentifierReference(listOf("_prog8_float_eval_result"), value.position)
variable.linkParents(value)
val assign = AsmAssignment(AsmAssignSource.fromAstSource(value, program, asmgen),
AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.FLOAT, null, variableAsmName = asmgen.asmVariableName(variable)),
false, Position.DUMMY)
asmgen.translateNormalAssignment(assign)
val addr = AddressOf(variable, value.position)
AsmAssignSource.fromAstSource(addr, program, asmgen)
}
}
}

View File

@ -5,6 +5,8 @@
; Note: this program is compatible with C64 and CX16.
; TODO why has the prg become bigger since register args?
; TODO doesn't work properly anymore
main {

View File

@ -3,6 +3,7 @@
%import conv
; TODO add all other Elite's ships, show their name, advance to next ship on keypress
; TODO doesn't draw anything on cx16 anymore...
main {

View File

@ -5,6 +5,7 @@
; Note: this program is compatible with C64 and CX16.
; TODO why has the prg become bigger since register args?
; TODO doesn't work properly anymore
main {

View File

@ -6,6 +6,17 @@
main {
sub start() {
float t = 0.0
repeat 10 {
float cosa = cos(t)
float sina = sin(t)
float cosb = cos(t*0.33)
float sinb = sin(t*0.33)
float cosc = cos(t*0.78)
float sinc = sin(t*0.78)
}
testX()
}

View File

@ -3,6 +3,7 @@
%import graphics
%zeropage floatsafe
; TODO doesn't work anymore
main {