optimize ubyte -> uword type casts more

This commit is contained in:
Irmen de Jong 2020-12-31 01:02:36 +01:00
parent 89230ade7a
commit c989abe265
4 changed files with 55 additions and 32 deletions

View File

@ -319,6 +319,52 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
return
}
if(origTypeCastExpression.type == DataType.UBYTE) {
val parentTc = origTypeCastExpression.parent as? TypecastExpression
if(parentTc!=null && parentTc.type==DataType.UWORD) {
// typecast something to ubyte and directly back to uword
// generate code for lsb(value) here instead of the ubyte typecast
return assignCastViaLsbFunc(value, target)
}
}
if(valueDt==DataType.UBYTE) {
when(target.register) {
RegisterOrPair.A,
RegisterOrPair.X,
RegisterOrPair.Y -> {
// 'cast' a ubyte value to a byte register; no cast needed at all
return assignExpressionToRegister(value, target.register)
}
RegisterOrPair.AX,
RegisterOrPair.AY,
RegisterOrPair.XY,
in Cx16VirtualRegisters -> {
// cast an ubyte value to a 16 bits register, just assign it and make use of the value extension
return assignExpressionToRegister(value, target.register!!)
}
else -> {}
}
} else if(valueDt==DataType.UWORD) {
when(target.register) {
RegisterOrPair.A,
RegisterOrPair.X,
RegisterOrPair.Y -> {
// cast an uword to a byte register, do this via lsb(value)
// generate code for lsb(value) here instead of the ubyte typecast
return assignCastViaLsbFunc(value, target)
}
RegisterOrPair.AX,
RegisterOrPair.AY,
RegisterOrPair.XY,
in Cx16VirtualRegisters -> {
// 'cast' uword into a 16 bits register, just assign it
return assignExpressionToRegister(value, target.register!!)
}
else -> {}
}
}
// give up, do it via eval stack
// TODO optimize typecasts for more special cases?
// note: cannot use assignTypeCastedValue because that is ourselves :P
@ -328,6 +374,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
assignStackValue(target)
}
private fun assignCastViaLsbFunc(value: Expression, target: AsmAssignTarget) {
val lsb = FunctionCall(IdentifierReference(listOf("lsb"), value.position), mutableListOf(value), value.position)
lsb.linkParents(value.parent)
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UBYTE, expression = lsb)
val assign = AsmAssignment(src, target, false, value.position)
translateNormalAssignment(assign)
}
private fun assignTypecastedFloatFAC1(targetAsmVarName: String, targetDt: DataType) {
if(targetDt==DataType.FLOAT)

View File

@ -18,7 +18,6 @@ main {
uword anglex
uword angley
uword anglez
ubyte timer_jiffies
repeat {
rotate_vertices(msb(anglex), msb(angley), msb(anglez))

View File

@ -14,7 +14,7 @@ main {
repeat {
c64.CHROUT(19) ; HOME
txt.print("\n yyyy-mm-dd HH:MM:SS.jj\n\n")
cx16.clock_get_date_time()
void cx16.clock_get_date_time()
c64.CHROUT(' ')
print_date()
c64.CHROUT(' ')

View File

@ -1,43 +1,13 @@
%import test_stack
%import textio
%import floats
%zeropage basicsafe
%option no_sysinit
main {
sub start () {
uword cnt
ubyte ub
; TODO differences between:
repeat cnt as ubyte { ; TODO this goes via stack
ub++
}
repeat lsb(cnt) { ; TODO this doesnt
ub++
}
; TODO stack based evaluation for this function call even when it's inlined:
next_pixel((cnt as ubyte) + 30)
test_stack.test()
}
inline asmsub next_pixel(ubyte color @A) {
%asm {{
nop
}}
}
}