implemented reverse(floatarray) builtin function

This commit is contained in:
Irmen de Jong 2020-03-11 23:08:08 +01:00
parent 8d1a4588d3
commit aa36acd65a
6 changed files with 252 additions and 58 deletions

View File

@ -1577,96 +1577,182 @@ _work3 .word 0
reverse_b .proc
; --- reverse an array of bytes (in-place)
; inputs: pointer to array in c64.SCRATCH_ZPWORD1, length in A
_left_index = c64.SCRATCH_ZPWORD2
_right_index = c64.SCRATCH_ZPWORD2+1
pha
_index_right = c64.SCRATCH_ZPWORD2
_index_left = c64.SCRATCH_ZPWORD2+1
_loop_count = c64.SCRATCH_ZPREG
sta _loop_count
lsr _loop_count
sec
sbc #1
sta _left_index
sta _index_right
lda #0
sta _index_left
_loop ldy _index_right
lda (c64.SCRATCH_ZPWORD1),y
pha
ldy _index_left
lda (c64.SCRATCH_ZPWORD1),y
ldy _index_right
sta (c64.SCRATCH_ZPWORD1),y
pla
ldy _index_left
sta (c64.SCRATCH_ZPWORD1),y
inc _index_left
dec _index_right
dec _loop_count
bne _loop
rts
.pend
reverse_f .proc
; --- reverse an array of floats
_left_index = c64.SCRATCH_ZPWORD2
_right_index = c64.SCRATCH_ZPWORD2+1
_loop_count = c64.SCRATCH_ZPREG
pha
sta c64.SCRATCH_ZPREG
asl a
asl a
clc
adc c64.SCRATCH_ZPREG ; *5 because float
sec
sbc #5
sta _right_index
lda #0
sta _left_index
pla
lsr a
tay
_loop sty c64.SCRATCH_ZPREG
sta _loop_count
_loop ; push the left indexed float on the stack
ldy _left_index
lda (c64.SCRATCH_ZPWORD1),y
pha
iny
lda (c64.SCRATCH_ZPWORD1),y
pha
iny
lda (c64.SCRATCH_ZPWORD1),y
pha
iny
lda (c64.SCRATCH_ZPWORD1),y
pha
iny
lda (c64.SCRATCH_ZPWORD1),y
pha
; copy right index float to left index float
ldy _right_index
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
sta (c64.SCRATCH_ZPWORD1),y
pla
ldy _right_index
sta (c64.SCRATCH_ZPWORD1),y
inc _left_index
inc _right_index
dec _left_index
ldy c64.SCRATCH_ZPREG
ldy _right_index
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
sta (c64.SCRATCH_ZPWORD1),y
inc _left_index
inc _right_index
ldy _right_index
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
sta (c64.SCRATCH_ZPWORD1),y
inc _left_index
inc _right_index
ldy _right_index
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
sta (c64.SCRATCH_ZPWORD1),y
inc _left_index
inc _right_index
ldy _right_index
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
sta (c64.SCRATCH_ZPWORD1),y
; pop the float off the stack into the right index float
ldy _right_index
pla
sta (c64.SCRATCH_ZPWORD1),y
dey
pla
sta (c64.SCRATCH_ZPWORD1),y
dey
pla
sta (c64.SCRATCH_ZPWORD1),y
dey
pla
sta (c64.SCRATCH_ZPWORD1),y
dey
pla
sta (c64.SCRATCH_ZPWORD1),y
inc _left_index
lda _right_index
sec
sbc #9
sta _right_index
dec _loop_count
bne _loop
rts
.pend
reverse_w .proc
; --- reverse an array of words (in-place)
; inputs: pointer to array in c64.SCRATCH_ZPWORD1, length in A
_left_index = c64.SCRATCH_ZPWORD2
_right_index = c64.SCRATCH_ZPWORD2+1
_index_first = c64.SCRATCH_ZPWORD2
_index_second = c64.SCRATCH_ZPWORD2+1
_loop_count = c64.SCRATCH_ZPREG
pha
asl a ; *2 because words
sec
sbc #2
sta _left_index
sta _index_first
lda #0
sta _right_index
sta _index_second
pla
lsr a
pha
tay
sta _loop_count
; first reverse the lsbs
_loop_lo sty c64.SCRATCH_ZPREG
ldy _left_index
_loop_lo ldy _index_first
lda (c64.SCRATCH_ZPWORD1),y
pha
ldy _right_index
ldy _index_second
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
ldy _index_first
sta (c64.SCRATCH_ZPWORD1),y
pla
ldy _right_index
ldy _index_second
sta (c64.SCRATCH_ZPWORD1),y
inc _right_index
inc _right_index
dec _left_index
dec _left_index
ldy c64.SCRATCH_ZPREG
dey
inc _index_second
inc _index_second
dec _index_first
dec _index_first
dec _loop_count
bne _loop_lo
; now reverse the msbs
dec _right_index
inc _left_index
inc _left_index
inc _left_index
dec _index_second
inc _index_first
inc _index_first
inc _index_first
pla
tay
_loop_hi sty c64.SCRATCH_ZPREG
ldy _left_index
sta _loop_count
_loop_hi ldy _index_first
lda (c64.SCRATCH_ZPWORD1),y
pha
ldy _right_index
ldy _index_second
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
ldy _index_first
sta (c64.SCRATCH_ZPWORD1),y
pla
ldy _right_index
ldy _index_second
sta (c64.SCRATCH_ZPWORD1),y
dec _right_index
dec _right_index
inc _left_index
inc _left_index
ldy c64.SCRATCH_ZPREG
dey
dec _index_second
dec _index_second
inc _index_first
inc _index_first
dec _loop_count
bne _loop_hi
rts

View File

@ -546,7 +546,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
jsr prog8_lib.reverse_w
""")
}
DataType.ARRAY_F -> TODO("reverse floats (consider another solution if possible - this will be quite slow, if ever implemented)")
DataType.ARRAY_F -> {
asmgen.out("""
lda #<$varName
ldy #>$varName
sta ${C64Zeropage.SCRATCH_W1}
sty ${C64Zeropage.SCRATCH_W1 + 1}
lda #$numElements
jsr prog8_lib.reverse_f
""")
}
else -> throw AssemblyError("weird type")
}
}

View File

@ -13,7 +13,7 @@ import kotlin.math.pow
/*
todo add more expression optimizations
Also see https://egorbo.com/peephole-optimizations.html
Investigate what optimizations binaryen has, also see https://egorbo.com/peephole-optimizations.html
*/

View File

@ -16,7 +16,7 @@ import kotlin.math.floor
/*
TODO: remove unreachable code?
TODO: proper inlining of tiny subroutines (correctly renaming/relocating all variables in them and refs to those as well, or restrict to subs without variables?)
TODO: proper inlining of tiny subroutines (at first, restrict to subs without parameters and variables in them, and build it up from there: correctly renaming/relocating all variables in them and refs to those as well)
*/
@ -263,7 +263,7 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV
if(constvalue!=null) {
return if(constvalue.asBooleanValue){
// always true -> keep only if-part
printWarning("condition is always true", ifStatement.position) // TODO don't warn this if the condition is just the single value 'true'
printWarning("condition is always true", ifStatement.position)
optimizationsDone++
ifStatement.truepart
} else {

View File

@ -222,7 +222,7 @@ class AstVm(val program: Program, compilationTarget: String) {
when {
jx.generatedLabel != null -> {
val label = entrypoint.getLabelOrVariable(jx.generatedLabel) as Label
TODO("generatedlabel $label")
TODO("astvm handle generatedlabel $label")
}
jx.identifier != null -> {
when (val jumptarget = entrypoint.lookup(jx.identifier.nameInSource, jx.identifier.parent)) {
@ -359,7 +359,7 @@ class AstVm(val program: Program, compilationTarget: String) {
}
}
else -> {
TODO("weird call $target")
throw VmExecutionException("weird call target $target")
}
}
}
@ -467,7 +467,7 @@ class AstVm(val program: Program, compilationTarget: String) {
BranchCondition.NE, BranchCondition.NZ -> if(statusflags.zero) executeAnonymousScope(stmt.truepart) else executeAnonymousScope(stmt.elsepart)
BranchCondition.MI, BranchCondition.NEG -> if(statusflags.negative) executeAnonymousScope(stmt.truepart) else executeAnonymousScope(stmt.elsepart)
BranchCondition.PL, BranchCondition.POS -> if(statusflags.negative) executeAnonymousScope(stmt.truepart) else executeAnonymousScope(stmt.elsepart)
BranchCondition.VS, BranchCondition.VC -> TODO("overflow status")
BranchCondition.VS, BranchCondition.VC -> TODO("astvm branch on overflow status")
}
}
is ForLoop -> {
@ -544,7 +544,7 @@ class AstVm(val program: Program, compilationTarget: String) {
}
}
else -> {
TODO("implement $stmt")
TODO("astvm implement statement $stmt")
}
}
}
@ -649,7 +649,7 @@ class AstVm(val program: Program, compilationTarget: String) {
target.register != null -> {
runtimeVariables.set(program.namespace, target.register.name, value)
}
else -> TODO("assign $target")
else -> TODO("assign weird target $target")
}
}
@ -775,7 +775,7 @@ class AstVm(val program: Program, compilationTarget: String) {
val numericpart = argString.takeWhile { it.isDigit() }
result = RuntimeValueNumeric(DataType.UWORD, numericpart.toInt() and 65535)
}
else -> TODO("syscall ${sub.scopedname} $sub")
else -> TODO("astvm implement syscall ${sub.scopedname} $sub")
}
return result
@ -996,7 +996,7 @@ class AstVm(val program: Program, compilationTarget: String) {
else -> RuntimeValueNumeric(DataType.BYTE, 1)
}
}
else -> TODO("builtin function $name")
else -> TODO("astvm implement builtin function $name")
}
}
}

View File

@ -1,28 +1,127 @@
%import c64flt
%zeropage basicsafe
main {
sub start() {
ubyte[] uba = [1,2,3]
byte[] bba = [1,2,3]
uword[] uwa = [1111,2222,3333]
word[] wwa = [1111,2222,3333]
ubyte ub
for ub in 12 to 3 step -1 {
byte bb
uword uw
word ww
for ub in uba {
c64scr.print_ub(ub)
c64scr.print(",")
}
c64scr.print("\n")
for ub in 12 to 3 step -4 {
for bb in bba {
c64scr.print_b(bb)
c64scr.print(",")
}
c64scr.print("\n")
for uw in uwa {
c64scr.print_uw(uw)
c64scr.print(",")
}
c64scr.print("\n")
for ww in wwa {
c64scr.print_w(ww)
c64scr.print(",")
}
c64scr.print("\n")
for ub in [1,2,3] {
c64scr.print_ub(ub)
c64scr.print(",")
}
; c64scr.print("\n")
; for bb in [1,2,3] { ; TODO fix array literal conversion error
; c64scr.print_b(bb)
; c64scr.print(",")
; }
c64scr.print("\n")
for uw in [1111,2222,3333] {
c64scr.print_uw(uw)
c64scr.print(",")
}
; c64scr.print("\n")
; for ww in [1111,2222,3333] { ; TODO fix array literal conversion error
; c64scr.print_w(ww)
; c64scr.print(",")
; }
c64scr.print("\n")
ubyte[] ubb1 = [ 1 ]
ubyte[] ubb2 = [ 1, 2]
ubyte[] ubb3 = [ 1,2,3 ]
ubyte[] ubb4 = [ 1,2,3,4 ]
uword[] uww1 = [111]
uword[] uww2 = [111,222]
uword[] uww3 = [111,222,333]
uword[] uww4 = [111,222,333,444]
reverse(ubb1)
reverse(ubb2)
reverse(ubb3)
reverse(ubb4)
reverse(uww1)
reverse(uww2)
reverse(uww3)
reverse(uww4)
for ub in ubb1 {
c64scr.print_ub(ub)
c64scr.print(",")
}
c64scr.print("\n")
for ub in 12 downto 3 {
for ub in ubb2 {
c64scr.print_ub(ub)
c64scr.print(",")
}
c64scr.print("\n")
for ub in 12 downto 3 step -4 {
for ub in ubb3 {
c64scr.print_ub(ub)
c64scr.print(",")
}
c64scr.print("\n")
for ub in ubb4 {
c64scr.print_ub(ub)
c64scr.print(",")
}
c64scr.print("\n")
for uw in uww1 {
c64scr.print_uw(uw)
c64scr.print(",")
}
c64scr.print("\n")
for uw in uww2 {
c64scr.print_uw(uw)
c64scr.print(",")
}
c64scr.print("\n")
for uw in uww3 {
c64scr.print_uw(uw)
c64scr.print(",")
}
c64scr.print("\n")
for uw in uww4 {
c64scr.print_uw(uw)
c64scr.print(",")
}
c64scr.print("\n")
float[] fa = [1.1, 2.2, 3.3, 4.4, 5.5]
reverse(fa)
for ub in 0 to len(fa)-1 {
c64flt.print_f(fa[ub])
c64scr.print(",")
}
c64scr.print("\n")
}
}