mirror of
https://github.com/irmen/prog8.git
synced 2025-01-12 19:29:50 +00:00
fix swap() code for pointervars
This commit is contained in:
parent
c7eafd7c79
commit
5fe6aa2800
@ -710,6 +710,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
||||
val first = fcall.args[0]
|
||||
val second = fcall.args[1]
|
||||
|
||||
val arrayVarDecl1 = (first as? ArrayIndexedExpression)?.arrayvar?.targetVarDecl(program)
|
||||
val arrayVarDecl2 = (second as? ArrayIndexedExpression)?.arrayvar?.targetVarDecl(program)
|
||||
if((arrayVarDecl1!=null && !arrayVarDecl1.isArray) || (arrayVarDecl2!=null && !arrayVarDecl2.isArray))
|
||||
throw AssemblyError("no asm gen for swapping bytes to and/or from indexed pointer var ${fcall.position}")
|
||||
|
||||
// optimized simple case: swap two variables
|
||||
if(first is IdentifierReference && second is IdentifierReference) {
|
||||
val firstName = asmgen.asmVariableName(first)
|
||||
@ -787,11 +792,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
||||
) {
|
||||
if(firstOffset is NumericLiteral && secondOffset is NumericLiteral) {
|
||||
if(firstOffset!=secondOffset) {
|
||||
swapArrayValues(
|
||||
DataType.UBYTE,
|
||||
asmgen.asmVariableName(pointerVariable), firstOffset,
|
||||
asmgen.asmVariableName(pointerVariable), secondOffset
|
||||
)
|
||||
swapArrayBytesViaPointers(pointerVariable, firstOffset, pointerVariable, secondOffset)
|
||||
return
|
||||
}
|
||||
} else if(firstOffset is TypecastExpression && secondOffset is TypecastExpression) {
|
||||
@ -800,11 +801,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
||||
val secondOffsetVar = secondOffset.expression as? IdentifierReference
|
||||
if(firstOffsetVar!=null && secondOffsetVar!=null) {
|
||||
if(firstOffsetVar!=secondOffsetVar) {
|
||||
swapArrayValues(
|
||||
DataType.UBYTE,
|
||||
asmgen.asmVariableName(pointerVariable), firstOffsetVar,
|
||||
asmgen.asmVariableName(pointerVariable), secondOffsetVar
|
||||
)
|
||||
swapArrayBytesViaPointers(pointerVariable, firstOffsetVar, pointerVariable, secondOffsetVar)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -829,16 +826,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
||||
val secondNum = second.indexer.indexExpr as? NumericLiteral
|
||||
val secondVar = second.indexer.indexExpr as? IdentifierReference
|
||||
|
||||
if(firstNum!=null && secondNum!=null) {
|
||||
if (firstNum != null && secondNum != null) {
|
||||
swapArrayValues(elementDt, arrayVarName1, firstNum, arrayVarName2, secondNum)
|
||||
return
|
||||
} else if(firstVar!=null && secondVar!=null) {
|
||||
} else if (firstVar != null && secondVar != null) {
|
||||
swapArrayValues(elementDt, arrayVarName1, firstVar, arrayVarName2, secondVar)
|
||||
return
|
||||
} else if(firstNum!=null && secondVar!=null) {
|
||||
} else if (firstNum != null && secondVar != null) {
|
||||
swapArrayValues(elementDt, arrayVarName1, firstNum, arrayVarName2, secondVar)
|
||||
return
|
||||
} else if(firstVar!=null && secondNum!=null) {
|
||||
} else if (firstVar != null && secondNum != null) {
|
||||
swapArrayValues(elementDt, arrayVarName1, firstVar, arrayVarName2, secondNum)
|
||||
return
|
||||
}
|
||||
@ -895,6 +892,72 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
private fun swapArrayBytesViaPointers(
|
||||
firstZpPtr: IdentifierReference,
|
||||
firstOffset: NumericLiteral,
|
||||
secondZpPtr: IdentifierReference,
|
||||
secondOffset: NumericLiteral
|
||||
) {
|
||||
var firstZpPtrName = asmgen.asmSymbolName(firstZpPtr)
|
||||
if(!asmgen.isZpVar(firstZpPtr)) {
|
||||
asmgen.out(" lda $firstZpPtrName | sta P8ZP_SCRATCH_W1")
|
||||
asmgen.out(" lda $firstZpPtrName+1 | sta P8ZP_SCRATCH_W1+1")
|
||||
firstZpPtrName = "P8ZP_SCRATCH_W1"
|
||||
}
|
||||
var secondZpPtrName = asmgen.asmSymbolName(secondZpPtr)
|
||||
if(!asmgen.isZpVar(secondZpPtr)) {
|
||||
asmgen.out(" lda $secondZpPtrName | sta P8ZP_SCRATCH_W2")
|
||||
asmgen.out(" lda $secondZpPtrName+1 | sta P8ZP_SCRATCH_W2+1")
|
||||
secondZpPtrName = "P8ZP_SCRATCH_W2"
|
||||
}
|
||||
asmgen.out("""
|
||||
ldy #${firstOffset.number.toInt()}
|
||||
lda ($firstZpPtrName),y
|
||||
pha
|
||||
ldy #${secondOffset.number.toInt()}
|
||||
lda ($secondZpPtrName),y
|
||||
ldy #${firstOffset.number.toInt()}
|
||||
sta ($firstZpPtrName),y
|
||||
pla
|
||||
ldy #${secondOffset.number.toInt()}
|
||||
sta ($secondZpPtrName),y
|
||||
""")
|
||||
}
|
||||
|
||||
private fun swapArrayBytesViaPointers(
|
||||
firstZpPtr: IdentifierReference,
|
||||
index1Var: IdentifierReference,
|
||||
secondZpPtr: IdentifierReference,
|
||||
index2Var: IdentifierReference
|
||||
) {
|
||||
var firstZpPtrName = asmgen.asmSymbolName(firstZpPtr)
|
||||
if(!asmgen.isZpVar(firstZpPtr)) {
|
||||
asmgen.out(" lda $firstZpPtrName | sta P8ZP_SCRATCH_W1")
|
||||
asmgen.out(" lda $firstZpPtrName+1 | sta P8ZP_SCRATCH_W1+1")
|
||||
firstZpPtrName = "P8ZP_SCRATCH_W1"
|
||||
}
|
||||
var secondZpPtrName = asmgen.asmSymbolName(secondZpPtr)
|
||||
if(!asmgen.isZpVar(secondZpPtr)) {
|
||||
asmgen.out(" lda $secondZpPtrName | sta P8ZP_SCRATCH_W2")
|
||||
asmgen.out(" lda $secondZpPtrName+1 | sta P8ZP_SCRATCH_W2+1")
|
||||
secondZpPtrName = "P8ZP_SCRATCH_W2"
|
||||
}
|
||||
val index1Name = asmgen.asmVariableName(index1Var)
|
||||
val index2Name = asmgen.asmVariableName(index2Var)
|
||||
asmgen.out("""
|
||||
ldy $index1Name
|
||||
lda ($firstZpPtrName),y
|
||||
pha
|
||||
ldy $index2Name
|
||||
lda ($secondZpPtrName),y
|
||||
ldy $index1Name
|
||||
sta ($firstZpPtrName),y
|
||||
pla
|
||||
ldy $index2Name
|
||||
sta ($secondZpPtrName),y
|
||||
""")
|
||||
}
|
||||
|
||||
private fun swapArrayValues(elementDt: DataType, arrayVarName1: String, indexValue1: NumericLiteral, arrayVarName2: String, indexValue2: NumericLiteral) {
|
||||
val index1 = indexValue1.number.toInt() * program.memsizer.memorySize(elementDt)
|
||||
val index2 = indexValue2.number.toInt() * program.memsizer.memorySize(elementDt)
|
||||
|
@ -1,5 +1,5 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
%zeropage dontuse
|
||||
|
||||
|
||||
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
||||
@ -31,27 +31,78 @@ main {
|
||||
sub start() {
|
||||
; mcCarthy()
|
||||
|
||||
ubyte[20] sieve
|
||||
uword count=0
|
||||
if count < 256
|
||||
txt.print("<256 ok! 1\n")
|
||||
if count > 256
|
||||
txt.print(">256 nok! 2\n")
|
||||
count=257
|
||||
if count < 256
|
||||
txt.print("<256 nok! 3\n")
|
||||
if count > 256
|
||||
txt.print(">256 ok! 4\n")
|
||||
count=256
|
||||
ubyte value = 0
|
||||
ubyte size = 9
|
||||
ubyte[10] data = [11,22,33,4,5,6,7,8,9,10]
|
||||
uword bitmapbuf = &data
|
||||
|
||||
count=0
|
||||
while count < 256 { ; TODO fix this while loop
|
||||
txt.print_uw(count)
|
||||
; ; 11 22 33
|
||||
; txt.print_ub(bitmapbuf[0])
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[1])
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[2])
|
||||
; txt.nl()
|
||||
; rol(bitmapbuf[0])
|
||||
; rol(bitmapbuf[0])
|
||||
; txt.print_ub(bitmapbuf[0]) ; 44
|
||||
; txt.spc()
|
||||
; ror(bitmapbuf[0])
|
||||
; ror(bitmapbuf[0])
|
||||
; txt.print_ub(bitmapbuf[0]) ; 11
|
||||
; txt.nl()
|
||||
;
|
||||
; ; 22 44 66
|
||||
; txt.print_ub(bitmapbuf[0]*2)
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[1]*2)
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[2]*2)
|
||||
; txt.nl()
|
||||
|
||||
ubyte one = 1
|
||||
|
||||
bitmapbuf[0] = one
|
||||
bitmapbuf[1] = one+one
|
||||
bitmapbuf[2] = one+one+one
|
||||
bitmapbuf[2] += 4
|
||||
bitmapbuf[2] -= 2
|
||||
bitmapbuf[2] -= 2
|
||||
swap(bitmapbuf[0], bitmapbuf[1])
|
||||
|
||||
; 1 2 3
|
||||
txt.print_ub(bitmapbuf[0])
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[1])
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[2])
|
||||
txt.nl()
|
||||
|
||||
for value in data {
|
||||
txt.print_ub(value)
|
||||
txt.spc()
|
||||
count += 10
|
||||
}
|
||||
txt.nl()
|
||||
|
||||
; TODO why is this loop much larger in code than the one below.
|
||||
value = 0
|
||||
ubyte xx
|
||||
for xx in 0 to size-1 {
|
||||
value += bitmapbuf[xx]
|
||||
}
|
||||
txt.print_ub(value) ; 45
|
||||
txt.nl()
|
||||
|
||||
; TODO this one is much more compact
|
||||
value = 0
|
||||
uword srcptr = bitmapbuf
|
||||
repeat size {
|
||||
value += @(srcptr)
|
||||
srcptr++
|
||||
}
|
||||
txt.print_ub(value) ; 45
|
||||
txt.nl()
|
||||
|
||||
; ; a "pixelshader":
|
||||
; sys.gfx_enable(0) ; enable lo res screen
|
||||
; ubyte shifter
|
||||
|
Loading…
x
Reference in New Issue
Block a user