mirror of
https://github.com/irmen/prog8.git
synced 2024-10-02 13:57:28 +00:00
float swap() no longer uses evaluation stack but a single temp var instead + FAC1
This commit is contained in:
parent
37a46aa2cf
commit
1605791f1b
@ -870,7 +870,7 @@ class AsmGen(private val program: Program,
|
||||
RegisterOrPair.XY,
|
||||
in Cx16VirtualRegisters -> assignmentAsmGen.assignRegisterpairWord(target, reg)
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
@ -875,22 +875,23 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
asmgen.translateNormalAssignment(assignSecond)
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
// via evaluation stack
|
||||
// TODO use 2 temporary variables instead
|
||||
asmgen.translateExpression(first)
|
||||
asmgen.translateExpression(second)
|
||||
val assignFirst = AsmAssignment(
|
||||
AsmAssignSource(SourceStorageKind.STACK, program, asmgen, DataType.FLOAT),
|
||||
// via temp variable and FAC1
|
||||
asmgen.assignExpressionTo(first, AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.FLOAT, first.definingSubroutine, "floats.tempvar_swap_float"))
|
||||
asmgen.assignExpressionTo(second, AsmAssignTarget(TargetStorageKind.REGISTER, program, asmgen, DataType.FLOAT, null, register=RegisterOrPair.FAC1))
|
||||
asmgen.translateNormalAssignment(
|
||||
AsmAssignment(
|
||||
AsmAssignSource(SourceStorageKind.REGISTER, program, asmgen, datatype, register = RegisterOrPair.FAC1),
|
||||
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),
|
||||
false, program.memsizer, second.position
|
||||
true, program.memsizer, second.position
|
||||
)
|
||||
)
|
||||
asmgen.translateNormalAssignment(assignFirst)
|
||||
asmgen.translateNormalAssignment(assignSecond)
|
||||
}
|
||||
else -> throw AssemblyError("weird swap dt")
|
||||
}
|
||||
|
@ -1847,7 +1847,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
||||
}
|
||||
|
||||
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 rightIDt = expr.right.inferType(program)
|
||||
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 rightDt = rightIDt.getOr(DataType.UNDEFINED)
|
||||
// see if we can apply some optimized routines
|
||||
// TODO avoid using evaluation on stack everywhere
|
||||
when(expr.operator) {
|
||||
"+" -> {
|
||||
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)
|
||||
}
|
||||
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.right)
|
||||
when (leftDt) {
|
||||
|
@ -147,7 +147,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
||||
if(arg.isSimple) { // TODO FOR ALL ARG TYPES?
|
||||
// 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...
|
||||
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 target = AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, dt, sub)
|
||||
asmgen.assignExpressionTo(arg, target)
|
||||
|
@ -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,
|
||||
// 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?
|
||||
exprAsmgen.translateExpression(value)
|
||||
asmgen.translateExpression(value)
|
||||
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
|
||||
asmgen.signExtendStackLsb(assign.source.datatype)
|
||||
assignStackValue(assign.target)
|
||||
@ -262,11 +262,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
}
|
||||
SourceStorageKind.REGISTER -> {
|
||||
when(assign.source.datatype) {
|
||||
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}")
|
||||
}
|
||||
asmgen.assignRegister(assign.source.register!!, assign.target)
|
||||
}
|
||||
SourceStorageKind.STACK -> {
|
||||
assignStackValue(assign.target)
|
||||
|
@ -12,6 +12,7 @@ floats {
|
||||
const float PI = 3.141592653589793
|
||||
const float TWOPI = 6.283185307179586
|
||||
|
||||
ubyte[5] tempvar_swap_float ; used for some swap() operations
|
||||
|
||||
; ---- C64 basic and kernal ROM float constants and functions ----
|
||||
|
||||
|
@ -10,10 +10,11 @@ floats {
|
||||
; ---- 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.
|
||||
|
||||
|
||||
const float PI = 3.141592653589793
|
||||
const float TWOPI = 6.283185307179586
|
||||
|
||||
ubyte[5] tempvar_swap_float ; used for some swap() operations
|
||||
|
||||
|
||||
; ---- ROM float functions ----
|
||||
|
||||
|
@ -6,6 +6,7 @@ prog8_lib {
|
||||
%asminclude "library:prog8_lib.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)
|
||||
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)
|
||||
|
@ -53,6 +53,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
|
||||
decl.value = null
|
||||
if(decl.name.startsWith("retval_interm_") && decl.definingScope.name=="prog8_lib") {
|
||||
// no need to zero out the special internal returnvalue intermediates.
|
||||
// TODO these variables are no longer used???
|
||||
return noModifications
|
||||
}
|
||||
val nextStmt = decl.nextSibling()
|
||||
|
@ -1,15 +1,25 @@
|
||||
%import textio
|
||||
%import floats
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
uword xx=$2000
|
||||
ubyte yy=$30
|
||||
ubyte zz=9
|
||||
; sys.memset(xx+200, yy*2, zz+yy)
|
||||
; uword xx=$2000
|
||||
; ubyte yy=$30
|
||||
; ubyte zz=9
|
||||
; ; sys.memset(xx+200, yy*2, zz+yy)
|
||||
;
|
||||
; @($c030) = 10
|
||||
; @($c000+yy) *= 2
|
||||
; txt.print_ub(@($c030))
|
||||
|
||||
@($c030) = 10
|
||||
@($c000+yy) *= 2
|
||||
txt.print_ub(@($c030))
|
||||
float f1 = 1111.11
|
||||
float f2 = 2222.22
|
||||
float[] fa = [2222.22, 3333.33]
|
||||
|
||||
swap(f1, fa[1])
|
||||
floats.print_f(f1)
|
||||
txt.nl()
|
||||
floats.print_f(fa[1])
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user