mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
some more optimized in-array assignments codegeneration
This commit is contained in:
parent
76cda82e23
commit
cb9825484d
@ -781,3 +781,18 @@ set_array_float .proc
|
||||
; -- copies the 5 bytes of the mflt value pointed to by SCRATCH_ZPWORD1,
|
||||
; into the 5 bytes pointed to by A/Y. Clobbers A,Y.
|
||||
.pend
|
||||
|
||||
|
||||
swap_floats .proc
|
||||
; -- swap floats pointed to by SCRATCH_ZPWORD1, SCRATCH_ZPWORD2
|
||||
ldy #4
|
||||
- lda (c64.SCRATCH_ZPWORD1),y
|
||||
pha
|
||||
lda (c64.SCRATCH_ZPWORD2),y
|
||||
sta (c64.SCRATCH_ZPWORD1),y
|
||||
pla
|
||||
sta (c64.SCRATCH_ZPWORD2),y
|
||||
dey
|
||||
bpl -
|
||||
rts
|
||||
.pend
|
||||
|
@ -1 +1 @@
|
||||
2.2
|
||||
2.3-SNAPSHOT
|
||||
|
@ -731,6 +731,8 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
|
||||
fun targetVarDecl(namespace: INameScope): VarDecl? = targetStatement(namespace) as? VarDecl
|
||||
fun targetSubroutine(namespace: INameScope): Subroutine? = targetStatement(namespace) as? Subroutine
|
||||
|
||||
override fun equals(other: Any?) = other is IdentifierReference && other.nameInSource==nameInSource
|
||||
|
||||
override fun linkParents(parent: Node) {
|
||||
this.parent = parent
|
||||
}
|
||||
|
@ -691,7 +691,6 @@ internal class AsmGen(private val program: Program,
|
||||
loopEndLabels.push(endLabel)
|
||||
loopContinueLabels.push(whileLabel)
|
||||
out(whileLabel)
|
||||
// TODO optimize for the simple cases, can we avoid stack use?
|
||||
expressionsAsmGen.translateExpression(stmt.condition)
|
||||
val conditionDt = stmt.condition.inferType(program)
|
||||
if(!conditionDt.isKnown)
|
||||
@ -720,7 +719,6 @@ internal class AsmGen(private val program: Program,
|
||||
loopEndLabels.push(endLabel)
|
||||
loopContinueLabels.push(repeatLabel)
|
||||
out(repeatLabel)
|
||||
// TODO optimize this for the simple cases, can we avoid stack use?
|
||||
translate(stmt.body)
|
||||
expressionsAsmGen.translateExpression(stmt.untilCondition)
|
||||
val conditionDt = stmt.untilCondition.inferType(program)
|
||||
|
@ -167,33 +167,108 @@ internal class AssignmentAsmGen(private val program: Program, private val errors
|
||||
TODO("$assign")
|
||||
}
|
||||
is ArrayIndexedExpression -> {
|
||||
if(assign.aug_op != "setvalue")
|
||||
return false // we don't put effort into optimizing anything beside simple assignment
|
||||
val valueArrayExpr = assign.value as ArrayIndexedExpression
|
||||
val valueArrayIndex = valueArrayExpr.arrayspec.index
|
||||
if(valueArrayIndex is RegisterExpr || arrayIndex is RegisterExpr) {
|
||||
throw AssemblyError("cannot generate code for array operations with registers as index")
|
||||
}
|
||||
val valueVariablename = asmgen.asmIdentifierName(valueArrayExpr.identifier)
|
||||
val valueDt = valueArrayExpr.identifier.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
when(arrayDt) {
|
||||
DataType.ARRAY_UB -> {
|
||||
if (arrayDt != DataType.ARRAY_B && arrayDt != DataType.ARRAY_UB && arrayDt != DataType.STR)
|
||||
throw AssemblyError("assignment to array: expected byte array or string")
|
||||
if (assign.aug_op == "setvalue") {
|
||||
if (valueArrayIndex is NumericLiteralValue)
|
||||
asmgen.out(" ldy #${valueArrayIndex.number.toHex()}")
|
||||
else
|
||||
asmgen.translateArrayIndexIntoY(valueArrayExpr)
|
||||
asmgen.out(" lda $valueVariablename,y")
|
||||
if (arrayIndex is NumericLiteralValue)
|
||||
asmgen.out(" ldy #${arrayIndex.number.toHex()}")
|
||||
else
|
||||
asmgen.translateArrayIndexIntoY(targetArray)
|
||||
asmgen.out(" sta $targetName,y")
|
||||
} else {
|
||||
return false // TODO optimize
|
||||
}
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> {
|
||||
if (valueArrayIndex is NumericLiteralValue)
|
||||
asmgen.out(" ldy #${valueArrayIndex.number.toHex()}")
|
||||
else
|
||||
asmgen.translateArrayIndexIntoY(valueArrayExpr)
|
||||
asmgen.out(" lda $valueVariablename,y")
|
||||
if (arrayIndex is NumericLiteralValue)
|
||||
asmgen.out(" ldy #${arrayIndex.number.toHex()}")
|
||||
else
|
||||
asmgen.translateArrayIndexIntoY(targetArray)
|
||||
asmgen.out(" sta $targetName,y")
|
||||
}
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||
if (valueArrayIndex is NumericLiteralValue)
|
||||
asmgen.out(" ldy #2*${valueArrayIndex.number.toHex()}")
|
||||
else {
|
||||
asmgen.translateArrayIndexIntoA(valueArrayExpr)
|
||||
asmgen.out(" asl a | tay")
|
||||
}
|
||||
asmgen.out("""
|
||||
lda $valueVariablename,y
|
||||
pha
|
||||
lda $valueVariablename+1,y
|
||||
pha
|
||||
""")
|
||||
if (arrayIndex is NumericLiteralValue)
|
||||
asmgen.out(" ldy #2*${arrayIndex.number.toHex()}")
|
||||
else {
|
||||
asmgen.translateArrayIndexIntoA(targetArray)
|
||||
asmgen.out(" asl a | tay")
|
||||
}
|
||||
asmgen.out("""
|
||||
pla
|
||||
sta $targetName+1,y
|
||||
pla
|
||||
sta $targetName,y
|
||||
""")
|
||||
return true
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
if (valueArrayIndex is NumericLiteralValue)
|
||||
asmgen.out(" ldy #5*${valueArrayIndex.number.toHex()}")
|
||||
else {
|
||||
asmgen.translateArrayIndexIntoA(valueArrayExpr)
|
||||
asmgen.out("""
|
||||
sta ${C64Zeropage.SCRATCH_REG}
|
||||
asl a
|
||||
asl a
|
||||
clc
|
||||
adc ${C64Zeropage.SCRATCH_REG}
|
||||
tay
|
||||
""")
|
||||
}
|
||||
asmgen.out("""
|
||||
lda $valueVariablename,y
|
||||
pha
|
||||
lda $valueVariablename+1,y
|
||||
pha
|
||||
lda $valueVariablename+2,y
|
||||
pha
|
||||
lda $valueVariablename+3,y
|
||||
pha
|
||||
lda $valueVariablename+4,y
|
||||
pha
|
||||
""")
|
||||
if (arrayIndex is NumericLiteralValue)
|
||||
asmgen.out(" ldy #5*${arrayIndex.number.toHex()}")
|
||||
else {
|
||||
asmgen.translateArrayIndexIntoA(targetArray)
|
||||
asmgen.out("""
|
||||
sta ${C64Zeropage.SCRATCH_REG}
|
||||
asl a
|
||||
asl a
|
||||
clc
|
||||
adc ${C64Zeropage.SCRATCH_REG}
|
||||
tay
|
||||
""")
|
||||
}
|
||||
asmgen.out("""
|
||||
pla
|
||||
sta $targetName+4,y
|
||||
pla
|
||||
sta $targetName+3,y
|
||||
pla
|
||||
sta $targetName+2,y
|
||||
pla
|
||||
sta $targetName+1,y
|
||||
pla
|
||||
sta $targetName,y
|
||||
""")
|
||||
return true
|
||||
}
|
||||
DataType.ARRAY_B -> TODO()
|
||||
DataType.ARRAY_UW -> TODO()
|
||||
DataType.ARRAY_W -> TODO()
|
||||
DataType.ARRAY_F -> TODO()
|
||||
else -> throw AssemblyError("assignment to array: invalid array dt")
|
||||
}
|
||||
return true
|
||||
|
@ -581,23 +581,63 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
ldy $firstName
|
||||
lda $secondName
|
||||
sta $firstName
|
||||
tya
|
||||
sta $secondName
|
||||
sty $secondName
|
||||
ldy $firstName+1
|
||||
lda $secondName+1
|
||||
sta $firstName+1
|
||||
tya
|
||||
sta $secondName+1
|
||||
sty $secondName+1
|
||||
""")
|
||||
return
|
||||
}
|
||||
if(dt.istype(DataType.FLOAT)) {
|
||||
TODO("optimized case for swapping 2 float vars-- asm subroutine")
|
||||
asmgen.out("""
|
||||
lda #<$firstName
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
lda #>$firstName
|
||||
sta ${C64Zeropage.SCRATCH_W1+1}
|
||||
lda #<$secondName
|
||||
sta ${C64Zeropage.SCRATCH_W2}
|
||||
lda #>$secondName
|
||||
sta ${C64Zeropage.SCRATCH_W2+1}
|
||||
jsr c64flt.swap_floats
|
||||
""")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// TODO more optimized cases? for instance swapping elements of array vars?
|
||||
// TODO more optimized cases?
|
||||
|
||||
// if(first is ArrayIndexedExpression && second is ArrayIndexedExpression && first.identifier == second.identifier) {
|
||||
// // swapping two elements of an array
|
||||
// // we optimize just some simple cases here: same array, const/var/reg index.
|
||||
// val arrayName = asmgen.asmIdentifierName(first.identifier)
|
||||
// val dt = first.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
// val constIndex1 = first.arrayspec.index.constValue(program)
|
||||
// val constIndex2 = second.arrayspec.index.constValue(program)
|
||||
// val varIndex1 = first.arrayspec.index as? IdentifierReference
|
||||
// val varIndex2 = first.arrayspec.index as? IdentifierReference
|
||||
// val regIndex1 = (first.arrayspec.index as? RegisterExpr)?.register
|
||||
// val regIndex2 = (first.arrayspec.index as? RegisterExpr)?.register
|
||||
// when(dt) {
|
||||
// DataType.UBYTE, DataType.BYTE -> {
|
||||
// TODO("swap byte in array $arrayName")
|
||||
// }
|
||||
// DataType.UWORD, DataType.WORD -> {
|
||||
// // swap word in array
|
||||
// if(varIndex1!=null && varIndex2!=null){
|
||||
// TODO("swap word in array $arrayName with varindexes")
|
||||
// } else if(constIndex1!=null && constIndex2!=null) {
|
||||
// TODO("swap word in array $arrayName with constants")
|
||||
// } else if(regIndex1!=null && regIndex2!=null) {
|
||||
// TODO("swap word in array $arrayName with register indexes")
|
||||
// }
|
||||
// }
|
||||
// DataType.FLOAT -> {
|
||||
// TODO("swap float in array $arrayName")
|
||||
// }
|
||||
// else -> throw AssemblyError("invalid array dt")
|
||||
// }
|
||||
// }
|
||||
|
||||
// suboptimal code via the evaluation stack...
|
||||
asmgen.translateExpression(first)
|
||||
|
@ -143,9 +143,18 @@ main {
|
||||
for i1 in 0 to i {
|
||||
ubyte i2 = i1+1
|
||||
if(rotatedz[i1] > rotatedz[i2]) {
|
||||
swap(rotatedx[i1], rotatedx[i2])
|
||||
swap(rotatedy[i1], rotatedy[i2])
|
||||
swap(rotatedz[i1], rotatedz[i2])
|
||||
; swap(rotatedx[i1], rotatedx[i2]) ; TODO eventually, implment the swap()
|
||||
; swap(rotatedy[i1], rotatedy[i2])
|
||||
; swap(rotatedz[i1], rotatedz[i2])
|
||||
word tmp1 = rotatedx[i1]
|
||||
rotatedx[i1] = rotatedx[i2] ; TODO fix assignment error
|
||||
rotatedx[i2] = tmp1
|
||||
tmp1 = rotatedy[i1]
|
||||
rotatedy[i1] = rotatedy[i2]
|
||||
rotatedy[i2] = tmp1
|
||||
tmp1 = rotatedz[i1]
|
||||
rotatedz[i1] = rotatedz[i2]
|
||||
rotatedz[i2] = tmp1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,41 @@
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
A=42
|
||||
float[] fa=[1.1111,2.2222,3.3333,4.4444]
|
||||
ubyte[] uba = [1,2,3,4]
|
||||
word[] uwa = [1111,2222,3333,4444]
|
||||
ubyte ii = 1
|
||||
ubyte jj = 3
|
||||
|
||||
float f1 = 1.123456
|
||||
float f2 = 2.223344
|
||||
|
||||
swap(f1, f2)
|
||||
|
||||
swap(fa[0], fa[1])
|
||||
swap(uba[0], uba[1])
|
||||
swap(uwa[0], uwa[1])
|
||||
|
||||
swap(fa[A], fa[Y])
|
||||
swap(uba[A], uba[Y])
|
||||
swap(uwa[A], uwa[Y])
|
||||
|
||||
ubyte i1
|
||||
ubyte i2
|
||||
swap(fa[i1], fa[i2])
|
||||
swap(uba[i1], uba[i2])
|
||||
swap(uwa[i1], uwa[i2])
|
||||
|
||||
c64flt.print_f(f1)
|
||||
c64.CHROUT('\n')
|
||||
c64flt.print_f(f2)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
swap(f1,f2)
|
||||
c64flt.print_f(f1)
|
||||
c64.CHROUT('\n')
|
||||
c64flt.print_f(f2)
|
||||
c64.CHROUT('\n')
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user