mirror of
https://github.com/irmen/prog8.git
synced 2024-09-05 20:29:08 +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 first = fcall.args[0]
|
||||||
val second = fcall.args[1]
|
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
|
// optimized simple case: swap two variables
|
||||||
if(first is IdentifierReference && second is IdentifierReference) {
|
if(first is IdentifierReference && second is IdentifierReference) {
|
||||||
val firstName = asmgen.asmVariableName(first)
|
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 is NumericLiteral && secondOffset is NumericLiteral) {
|
||||||
if(firstOffset!=secondOffset) {
|
if(firstOffset!=secondOffset) {
|
||||||
swapArrayValues(
|
swapArrayBytesViaPointers(pointerVariable, firstOffset, pointerVariable, secondOffset)
|
||||||
DataType.UBYTE,
|
|
||||||
asmgen.asmVariableName(pointerVariable), firstOffset,
|
|
||||||
asmgen.asmVariableName(pointerVariable), secondOffset
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if(firstOffset is TypecastExpression && secondOffset is TypecastExpression) {
|
} 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
|
val secondOffsetVar = secondOffset.expression as? IdentifierReference
|
||||||
if(firstOffsetVar!=null && secondOffsetVar!=null) {
|
if(firstOffsetVar!=null && secondOffsetVar!=null) {
|
||||||
if(firstOffsetVar!=secondOffsetVar) {
|
if(firstOffsetVar!=secondOffsetVar) {
|
||||||
swapArrayValues(
|
swapArrayBytesViaPointers(pointerVariable, firstOffsetVar, pointerVariable, secondOffsetVar)
|
||||||
DataType.UBYTE,
|
|
||||||
asmgen.asmVariableName(pointerVariable), firstOffsetVar,
|
|
||||||
asmgen.asmVariableName(pointerVariable), secondOffsetVar
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -829,16 +826,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
|||||||
val secondNum = second.indexer.indexExpr as? NumericLiteral
|
val secondNum = second.indexer.indexExpr as? NumericLiteral
|
||||||
val secondVar = second.indexer.indexExpr as? IdentifierReference
|
val secondVar = second.indexer.indexExpr as? IdentifierReference
|
||||||
|
|
||||||
if(firstNum!=null && secondNum!=null) {
|
if (firstNum != null && secondNum != null) {
|
||||||
swapArrayValues(elementDt, arrayVarName1, firstNum, arrayVarName2, secondNum)
|
swapArrayValues(elementDt, arrayVarName1, firstNum, arrayVarName2, secondNum)
|
||||||
return
|
return
|
||||||
} else if(firstVar!=null && secondVar!=null) {
|
} else if (firstVar != null && secondVar != null) {
|
||||||
swapArrayValues(elementDt, arrayVarName1, firstVar, arrayVarName2, secondVar)
|
swapArrayValues(elementDt, arrayVarName1, firstVar, arrayVarName2, secondVar)
|
||||||
return
|
return
|
||||||
} else if(firstNum!=null && secondVar!=null) {
|
} else if (firstNum != null && secondVar != null) {
|
||||||
swapArrayValues(elementDt, arrayVarName1, firstNum, arrayVarName2, secondVar)
|
swapArrayValues(elementDt, arrayVarName1, firstNum, arrayVarName2, secondVar)
|
||||||
return
|
return
|
||||||
} else if(firstVar!=null && secondNum!=null) {
|
} else if (firstVar != null && secondNum != null) {
|
||||||
swapArrayValues(elementDt, arrayVarName1, firstVar, arrayVarName2, secondNum)
|
swapArrayValues(elementDt, arrayVarName1, firstVar, arrayVarName2, secondNum)
|
||||||
return
|
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) {
|
private fun swapArrayValues(elementDt: DataType, arrayVarName1: String, indexValue1: NumericLiteral, arrayVarName2: String, indexValue2: NumericLiteral) {
|
||||||
val index1 = indexValue1.number.toInt() * program.memsizer.memorySize(elementDt)
|
val index1 = indexValue1.number.toInt() * program.memsizer.memorySize(elementDt)
|
||||||
val index2 = indexValue2.number.toInt() * program.memsizer.memorySize(elementDt)
|
val index2 = indexValue2.number.toInt() * program.memsizer.memorySize(elementDt)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%zeropage dontuse
|
||||||
|
|
||||||
|
|
||||||
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
||||||
@ -31,27 +31,78 @@ main {
|
|||||||
sub start() {
|
sub start() {
|
||||||
; mcCarthy()
|
; mcCarthy()
|
||||||
|
|
||||||
ubyte[20] sieve
|
ubyte value = 0
|
||||||
uword count=0
|
ubyte size = 9
|
||||||
if count < 256
|
ubyte[10] data = [11,22,33,4,5,6,7,8,9,10]
|
||||||
txt.print("<256 ok! 1\n")
|
uword bitmapbuf = &data
|
||||||
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
|
|
||||||
|
|
||||||
count=0
|
; ; 11 22 33
|
||||||
while count < 256 { ; TODO fix this while loop
|
; txt.print_ub(bitmapbuf[0])
|
||||||
txt.print_uw(count)
|
; 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()
|
txt.spc()
|
||||||
count += 10
|
|
||||||
}
|
}
|
||||||
txt.nl()
|
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":
|
; ; a "pixelshader":
|
||||||
; sys.gfx_enable(0) ; enable lo res screen
|
; sys.gfx_enable(0) ; enable lo res screen
|
||||||
; ubyte shifter
|
; ubyte shifter
|
||||||
|
Loading…
Reference in New Issue
Block a user