float swap() no longer uses evaluation stack but a single temp var instead + FAC1

This commit is contained in:
Irmen de Jong 2021-11-06 03:28:42 +01:00
parent 37a46aa2cf
commit 1605791f1b
10 changed files with 42 additions and 31 deletions

View File

@ -870,7 +870,7 @@ class AsmGen(private val program: Program,
RegisterOrPair.XY, RegisterOrPair.XY,
in Cx16VirtualRegisters -> assignmentAsmGen.assignRegisterpairWord(target, reg) in Cx16VirtualRegisters -> assignmentAsmGen.assignRegisterpairWord(target, reg)
RegisterOrPair.FAC1 -> assignmentAsmGen.assignFAC1float(target) RegisterOrPair.FAC1 -> assignmentAsmGen.assignFAC1float(target)
RegisterOrPair.FAC2 -> throw AssemblyError("no support yet to assign FAC2 directly to something") RegisterOrPair.FAC2 -> TODO("no support yet to assign FAC2 directly to something")
else -> throw AssemblyError("invalid register") else -> throw AssemblyError("invalid register")
} }
} }

View File

@ -875,22 +875,23 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
asmgen.translateNormalAssignment(assignSecond) asmgen.translateNormalAssignment(assignSecond)
} }
DataType.FLOAT -> { DataType.FLOAT -> {
// via evaluation stack // via temp variable and FAC1
// TODO use 2 temporary variables instead asmgen.assignExpressionTo(first, AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.FLOAT, first.definingSubroutine, "floats.tempvar_swap_float"))
asmgen.translateExpression(first) asmgen.assignExpressionTo(second, AsmAssignTarget(TargetStorageKind.REGISTER, program, asmgen, DataType.FLOAT, null, register=RegisterOrPair.FAC1))
asmgen.translateExpression(second) asmgen.translateNormalAssignment(
val assignFirst = AsmAssignment( AsmAssignment(
AsmAssignSource(SourceStorageKind.STACK, program, asmgen, DataType.FLOAT), AsmAssignSource(SourceStorageKind.REGISTER, program, asmgen, datatype, register = RegisterOrPair.FAC1),
targetFromExpr(first, datatype), targetFromExpr(first, datatype),
false, program.memsizer, first.position true, program.memsizer, first.position
) )
val assignSecond = AsmAssignment( )
AsmAssignSource(SourceStorageKind.STACK, program, asmgen, DataType.FLOAT), asmgen.translateNormalAssignment(
AsmAssignment(
AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, datatype, "floats.tempvar_swap_float"),
targetFromExpr(second, datatype), targetFromExpr(second, datatype),
false, program.memsizer, second.position true, program.memsizer, second.position
)
) )
asmgen.translateNormalAssignment(assignFirst)
asmgen.translateNormalAssignment(assignSecond)
} }
else -> throw AssemblyError("weird swap dt") else -> throw AssemblyError("weird swap dt")
} }

View File

@ -1847,7 +1847,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
private fun translateExpression(expr: BinaryExpression) { private fun translateExpression(expr: BinaryExpression) {
// TODO needs to use optimized assembly generation like the assignment instructions. But avoid code duplication.... rewrite all expressions into assignment form? // Uses evalstack to evaluate the given expression.
// TODO we're slowly reducing the number of places where this is called and instead replace that by more efficient assignment-form code (using temp var or register for instance).
val leftIDt = expr.left.inferType(program) val leftIDt = expr.left.inferType(program)
val rightIDt = expr.right.inferType(program) val rightIDt = expr.right.inferType(program)
if(!leftIDt.isKnown || !rightIDt.isKnown) if(!leftIDt.isKnown || !rightIDt.isKnown)
@ -1856,7 +1857,6 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
val leftDt = leftIDt.getOr(DataType.UNDEFINED) val leftDt = leftIDt.getOr(DataType.UNDEFINED)
val rightDt = rightIDt.getOr(DataType.UNDEFINED) val rightDt = rightIDt.getOr(DataType.UNDEFINED)
// see if we can apply some optimized routines // see if we can apply some optimized routines
// TODO avoid using evaluation on stack everywhere
when(expr.operator) { when(expr.operator) {
"+" -> { "+" -> {
if(leftDt in IntegerDatatypes && rightDt in IntegerDatatypes) { if(leftDt in IntegerDatatypes && rightDt in IntegerDatatypes) {
@ -2147,7 +2147,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
translateCompareStrings(expr.left, expr.operator, expr.right) translateCompareStrings(expr.left, expr.operator, expr.right)
} }
else { else {
// the general, non-optimized cases TODO optimize more cases.... // the general, non-optimized cases TODO optimize more cases.... (or one day just don't use the evalstack at all anymore)
translateExpressionInternal(expr.left) translateExpressionInternal(expr.left)
translateExpressionInternal(expr.right) translateExpressionInternal(expr.right)
when (leftDt) { when (leftDt) {

View File

@ -147,7 +147,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
if(arg.isSimple) { // TODO FOR ALL ARG TYPES? if(arg.isSimple) { // TODO FOR ALL ARG TYPES?
// note this stuff below is needed to (eventually) avoid calling asmgen.translateExpression() // note this stuff below is needed to (eventually) avoid calling asmgen.translateExpression()
// TODO but This STILL requires the translateNormalAssignment() to be fixed to avoid stack eval for expressions... // TODO but This STILL requires the translateNormalAssignment() to be fixed to avoid stack eval for expressions...
println("*** ALT PARAM PASSING FOR ASMSUB $stmt $arg") // TODO DEBUG // println("*** ALT PARAM PASSING FOR ASMSUB $stmt $arg") // TODO DEBUG
val dt = arg.inferType(program).getOr(DataType.UNDEFINED) val dt = arg.inferType(program).getOr(DataType.UNDEFINED)
val target = AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, dt, sub) val target = AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, dt, sub)
asmgen.assignExpressionTo(arg, target) asmgen.assignExpressionTo(arg, target)

View File

@ -254,7 +254,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here, // (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
// because the code here is the implementation of exactly that...) // because the code here is the implementation of exactly that...)
// TODO FIX THIS... by using a temp var? so that it becomes augmentable assignment expression? // TODO FIX THIS... by using a temp var? so that it becomes augmentable assignment expression?
exprAsmgen.translateExpression(value) asmgen.translateExpression(value)
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes) if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
asmgen.signExtendStackLsb(assign.source.datatype) asmgen.signExtendStackLsb(assign.source.datatype)
assignStackValue(assign.target) assignStackValue(assign.target)
@ -262,11 +262,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
SourceStorageKind.REGISTER -> { SourceStorageKind.REGISTER -> {
when(assign.source.datatype) { asmgen.assignRegister(assign.source.register!!, assign.target)
DataType.UBYTE, DataType.BYTE -> assignRegisterByte(assign.target, assign.source.register!!.asCpuRegister())
DataType.UWORD, DataType.WORD, in PassByReferenceDatatypes -> assignRegisterpairWord(assign.target, assign.source.register!!)
else -> throw AssemblyError("invalid register dt ${assign.source.datatype}")
}
} }
SourceStorageKind.STACK -> { SourceStorageKind.STACK -> {
assignStackValue(assign.target) assignStackValue(assign.target)

View File

@ -12,6 +12,7 @@ floats {
const float PI = 3.141592653589793 const float PI = 3.141592653589793
const float TWOPI = 6.283185307179586 const float TWOPI = 6.283185307179586
ubyte[5] tempvar_swap_float ; used for some swap() operations
; ---- C64 basic and kernal ROM float constants and functions ---- ; ---- C64 basic and kernal ROM float constants and functions ----

View File

@ -10,10 +10,11 @@ floats {
; ---- this block contains C-64 compatible floating point related functions ---- ; ---- this block contains C-64 compatible floating point related functions ----
; the addresses are from cx16 V39 emulator and roms! they won't work on older versions. ; the addresses are from cx16 V39 emulator and roms! they won't work on older versions.
const float PI = 3.141592653589793 const float PI = 3.141592653589793
const float TWOPI = 6.283185307179586 const float TWOPI = 6.283185307179586
ubyte[5] tempvar_swap_float ; used for some swap() operations
; ---- ROM float functions ---- ; ---- ROM float functions ----

View File

@ -6,6 +6,7 @@ prog8_lib {
%asminclude "library:prog8_lib.asm" %asminclude "library:prog8_lib.asm"
%asminclude "library:prog8_funcs.asm" %asminclude "library:prog8_funcs.asm"
; TODO these retval variables are no longer used???
uword @zp retval_interm_uw ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size) uword @zp retval_interm_uw ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
word @zp retval_interm_w ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size) word @zp retval_interm_w ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
ubyte @zp retval_interm_ub ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size) ubyte @zp retval_interm_ub ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)

View File

@ -53,6 +53,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
decl.value = null decl.value = null
if(decl.name.startsWith("retval_interm_") && decl.definingScope.name=="prog8_lib") { if(decl.name.startsWith("retval_interm_") && decl.definingScope.name=="prog8_lib") {
// no need to zero out the special internal returnvalue intermediates. // no need to zero out the special internal returnvalue intermediates.
// TODO these variables are no longer used???
return noModifications return noModifications
} }
val nextStmt = decl.nextSibling() val nextStmt = decl.nextSibling()

View File

@ -1,15 +1,25 @@
%import textio %import textio
%import floats
%zeropage basicsafe %zeropage basicsafe
main { main {
sub start() { sub start() {
uword xx=$2000 ; uword xx=$2000
ubyte yy=$30 ; ubyte yy=$30
ubyte zz=9 ; ubyte zz=9
; sys.memset(xx+200, yy*2, zz+yy) ; ; sys.memset(xx+200, yy*2, zz+yy)
;
; @($c030) = 10
; @($c000+yy) *= 2
; txt.print_ub(@($c030))
@($c030) = 10 float f1 = 1111.11
@($c000+yy) *= 2 float f2 = 2222.22
txt.print_ub(@($c030)) float[] fa = [2222.22, 3333.33]
swap(f1, fa[1])
floats.print_f(f1)
txt.nl()
floats.print_f(fa[1])
} }
} }