mirror of
https://github.com/irmen/prog8.git
synced 2025-08-07 05:27:10 +00:00
getting rid of pointer[idx] in ast, instead always use @(ptr+idx)
This commit is contained in:
@@ -138,16 +138,16 @@ class PtAddressOf(position: Position) : PtExpression(DataType.UWORD, position) {
|
|||||||
|
|
||||||
class PtArrayIndexer(elementType: DataType, position: Position): PtExpression(elementType, position) {
|
class PtArrayIndexer(elementType: DataType, position: Position): PtExpression(elementType, position) {
|
||||||
val variable: PtIdentifier
|
val variable: PtIdentifier
|
||||||
get() = children[0] as PtIdentifier
|
get() {
|
||||||
|
require((children[0] as? PtIdentifier)?.type in ArrayDatatypes+DataType.STR) // TODO remove
|
||||||
|
return children[0] as PtIdentifier
|
||||||
|
}
|
||||||
val index: PtExpression
|
val index: PtExpression
|
||||||
get() = children[1] as PtExpression
|
get() = children[1] as PtExpression
|
||||||
|
|
||||||
val splitWords: Boolean
|
val splitWords: Boolean
|
||||||
get() = variable.type in SplitWordArrayTypes
|
get() = variable.type in SplitWordArrayTypes
|
||||||
|
|
||||||
val usesPointerVariable: Boolean
|
|
||||||
get() = variable.type==DataType.UWORD
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
require(elementType in NumericDatatypes)
|
require(elementType in NumericDatatypes)
|
||||||
}
|
}
|
||||||
|
@@ -677,7 +677,6 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
is PtArrayIndexer -> {
|
is PtArrayIndexer -> {
|
||||||
val indexer = fcall.args[0] as PtArrayIndexer
|
val indexer = fcall.args[0] as PtArrayIndexer
|
||||||
require(!indexer.usesPointerVariable)
|
|
||||||
val elementSize: Int
|
val elementSize: Int
|
||||||
val msbAdd: Int
|
val msbAdd: Int
|
||||||
if(indexer.splitWords) {
|
if(indexer.splitWords) {
|
||||||
@@ -846,8 +845,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val tempvar = asmgen.getTempVarName(DataType.FLOAT)
|
val tempvar = asmgen.getTempVarName(DataType.FLOAT)
|
||||||
asmgen.assignExpressionTo(fcall.args[1],
|
asmgen.assignExpressionToVariable(fcall.args[1], tempvar, DataType.FLOAT)
|
||||||
AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.FLOAT, fcall.definingISub(), fcall.position, tempvar, null, null, null, null))
|
|
||||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
|
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
pha
|
pha
|
||||||
|
@@ -91,22 +91,7 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
|||||||
val indexValue = constIndex * program.memsizer.memorySize(elementDt)
|
val indexValue = constIndex * program.memsizer.memorySize(elementDt)
|
||||||
when(elementDt) {
|
when(elementDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
if(targetArrayIdx.usesPointerVariable) {
|
asmgen.out(if (incr) " inc $asmArrayvarname+$indexValue" else " dec $asmArrayvarname+$indexValue")
|
||||||
asmgen.out("""
|
|
||||||
lda $asmArrayvarname
|
|
||||||
clc
|
|
||||||
adc #$indexValue
|
|
||||||
sta (+) +1
|
|
||||||
lda $asmArrayvarname+1
|
|
||||||
adc #0
|
|
||||||
sta (+) +2""")
|
|
||||||
if(incr)
|
|
||||||
asmgen.out("+\tinc ${'$'}ffff\t; modified")
|
|
||||||
else
|
|
||||||
asmgen.out("+\tdec ${'$'}ffff\t; modified")
|
|
||||||
} else {
|
|
||||||
asmgen.out(if (incr) " inc $asmArrayvarname+$indexValue" else " dec $asmArrayvarname+$indexValue")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
if(incr)
|
if(incr)
|
||||||
@@ -130,22 +115,7 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
|||||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, CpuRegister.X)
|
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, CpuRegister.X)
|
||||||
when(elementDt) {
|
when(elementDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
if(targetArrayIdx.usesPointerVariable) {
|
asmgen.out(if (incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
||||||
asmgen.out("""
|
|
||||||
txa
|
|
||||||
clc
|
|
||||||
adc $asmArrayvarname
|
|
||||||
sta (+) +1
|
|
||||||
lda $asmArrayvarname+1
|
|
||||||
adc #0
|
|
||||||
sta (+) +2""")
|
|
||||||
if(incr)
|
|
||||||
asmgen.out("+\tinc ${'$'}ffff\t; modified")
|
|
||||||
else
|
|
||||||
asmgen.out("+\tdec ${'$'}ffff\t; modified")
|
|
||||||
} else {
|
|
||||||
asmgen.out(if (incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
if(incr)
|
if(incr)
|
||||||
|
@@ -64,32 +64,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
val value = assign.source.array!!
|
val value = assign.source.array!!
|
||||||
val elementDt = assign.source.datatype
|
val elementDt = assign.source.datatype
|
||||||
val arrayVarName = asmgen.asmVariableName(value.variable)
|
val arrayVarName = asmgen.asmVariableName(value.variable)
|
||||||
|
|
||||||
if(value.usesPointerVariable) {
|
|
||||||
if(elementDt !in ByteDatatypes)
|
|
||||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
|
||||||
if(value.type != DataType.UBYTE)
|
|
||||||
throw AssemblyError("non-array var indexing requires bytes index")
|
|
||||||
if(asmgen.isTargetCpu(CpuType.CPU65c02) && (value.index as? PtNumber)?.number==0.0) {
|
|
||||||
if (asmgen.isZpVar(value.variable)) {
|
|
||||||
asmgen.out(" lda ($arrayVarName)")
|
|
||||||
} else {
|
|
||||||
asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1")
|
|
||||||
asmgen.out(" lda (P8ZP_SCRATCH_W1)")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y)
|
|
||||||
if (asmgen.isZpVar(value.variable)) {
|
|
||||||
asmgen.out(" lda ($arrayVarName),y")
|
|
||||||
} else {
|
|
||||||
asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1")
|
|
||||||
asmgen.out(" lda (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val constIndex = value.index.asConstInteger()
|
val constIndex = value.index.asConstInteger()
|
||||||
|
|
||||||
if(value.splitWords) {
|
if(value.splitWords) {
|
||||||
@@ -805,26 +779,11 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
if(!rightArrayIndexer.index.isSimple()) asmgen.out(" pha")
|
if(!rightArrayIndexer.index.isSimple()) asmgen.out(" pha")
|
||||||
asmgen.assignExpressionToRegister(rightArrayIndexer.index, RegisterOrPair.Y, false)
|
asmgen.assignExpressionToRegister(rightArrayIndexer.index, RegisterOrPair.Y, false)
|
||||||
if(!rightArrayIndexer.index.isSimple()) asmgen.out(" pla")
|
if(!rightArrayIndexer.index.isSimple()) asmgen.out(" pla")
|
||||||
if(rightArrayIndexer.usesPointerVariable && !asmgen.isZpVar(rightArrayIndexer.variable)) {
|
val arrayvarname = asmgen.asmSymbolName(rightArrayIndexer.variable)
|
||||||
asmgen.out("""
|
if (expr.operator == "+")
|
||||||
ldx ${rightArrayIndexer.variable.name}
|
asmgen.out(" clc | adc $arrayvarname,y")
|
||||||
stx P8ZP_SCRATCH_W1
|
else
|
||||||
ldx ${rightArrayIndexer.variable.name}+1
|
asmgen.out(" sec | sbc $arrayvarname,y")
|
||||||
stx P8ZP_SCRATCH_W1+1""")
|
|
||||||
if (expr.operator == "+")
|
|
||||||
asmgen.out(" clc | adc (P8ZP_SCRATCH_W1),y")
|
|
||||||
else
|
|
||||||
asmgen.out(" sec | sbc (P8ZP_SCRATCH_W1),y")
|
|
||||||
} else {
|
|
||||||
val arrayvarname = if (rightArrayIndexer.usesPointerVariable)
|
|
||||||
"(${rightArrayIndexer.variable.name})"
|
|
||||||
else
|
|
||||||
asmgen.asmSymbolName(rightArrayIndexer.variable)
|
|
||||||
if (expr.operator == "+")
|
|
||||||
asmgen.out(" clc | adc $arrayvarname,y")
|
|
||||||
else
|
|
||||||
asmgen.out(" sec | sbc $arrayvarname,y")
|
|
||||||
}
|
|
||||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
|
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
|
||||||
} else {
|
} else {
|
||||||
assignExpressionToRegister(left, RegisterOrPair.A, left.type==DataType.BYTE)
|
assignExpressionToRegister(left, RegisterOrPair.A, left.type==DataType.BYTE)
|
||||||
@@ -2836,21 +2795,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
storeRegisterAInMemoryAddress(target.memory!!)
|
storeRegisterAInMemoryAddress(target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
if(assignsIndexedPointerVar(target)) {
|
|
||||||
if (target.constArrayIndexValue==0u) {
|
|
||||||
asmgen.out(" lda $sourceName")
|
|
||||||
asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable)
|
|
||||||
} else {
|
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y)
|
|
||||||
if (asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
|
||||||
asmgen.out(" lda $sourceName | sta (${target.asmVarname}),y")
|
|
||||||
} else {
|
|
||||||
asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1")
|
|
||||||
asmgen.out(" lda $sourceName | sta (P8ZP_SCRATCH_W2),y")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(target.array!!.splitWords)
|
if(target.array!!.splitWords)
|
||||||
TODO("assign into split words ${target.position}")
|
TODO("assign into split words ${target.position}")
|
||||||
if (target.constArrayIndexValue!=null) {
|
if (target.constArrayIndexValue!=null) {
|
||||||
@@ -3256,87 +3200,29 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
if(target.array!!.splitWords)
|
if(target.array!!.splitWords)
|
||||||
throw AssemblyError("cannot assign byte to split word array here ${target.position}")
|
throw AssemblyError("cannot assign byte to split word array here ${target.position}")
|
||||||
|
|
||||||
if(assignsIndexedPointerVar(target)) {
|
// assign regular array indexing
|
||||||
// assign byte to a byte array via an uword pointervariable instead of a regular array variable
|
if (target.constArrayIndexValue!=null) {
|
||||||
if (target.constArrayIndexValue!=null) {
|
when (register) {
|
||||||
when (register) {
|
CpuRegister.A -> {}
|
||||||
CpuRegister.A -> {}
|
CpuRegister.X -> asmgen.out(" txa")
|
||||||
CpuRegister.X -> asmgen.out(" txa")
|
CpuRegister.Y -> asmgen.out(" tya")
|
||||||
CpuRegister.Y -> asmgen.out(" tya")
|
|
||||||
}
|
|
||||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
|
||||||
asmgen.out(" ldy #${target.constArrayIndexValue} | sta (${target.asmVarname}),y")
|
|
||||||
} else {
|
|
||||||
asmgen.out("""
|
|
||||||
ldy ${target.asmVarname}
|
|
||||||
sty P8ZP_SCRATCH_W1
|
|
||||||
ldy ${target.asmVarname}+1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
ldy #${target.constArrayIndexValue}
|
|
||||||
sta (P8ZP_SCRATCH_W1),y""")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}")
|
||||||
when (register) {
|
}
|
||||||
CpuRegister.A -> {}
|
else {
|
||||||
CpuRegister.X -> asmgen.out(" txa")
|
when (register) {
|
||||||
CpuRegister.Y -> asmgen.out(" tya")
|
CpuRegister.A -> {}
|
||||||
}
|
CpuRegister.X -> asmgen.out(" txa")
|
||||||
val indexVar = target.array.index as? PtIdentifier
|
CpuRegister.Y -> asmgen.out(" tya")
|
||||||
if(indexVar!=null) {
|
|
||||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
|
||||||
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y")
|
|
||||||
} else {
|
|
||||||
asmgen.out("""
|
|
||||||
ldy ${target.asmVarname}
|
|
||||||
sty P8ZP_SCRATCH_W1
|
|
||||||
ldy ${target.asmVarname}+1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
ldy ${asmgen.asmVariableName(indexVar)}
|
|
||||||
sta (P8ZP_SCRATCH_W1),y""")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
asmgen.saveRegisterStack(register, false)
|
|
||||||
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false)
|
|
||||||
asmgen.out(" pla")
|
|
||||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
|
||||||
asmgen.out(" sta (${target.asmVarname}),y")
|
|
||||||
} else {
|
|
||||||
asmgen.out("""
|
|
||||||
ldx ${target.asmVarname}
|
|
||||||
stx P8ZP_SCRATCH_W1
|
|
||||||
ldx ${target.asmVarname}+1
|
|
||||||
stx P8ZP_SCRATCH_W1+1
|
|
||||||
sta (P8ZP_SCRATCH_W1),y""")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
val indexVar = target.array.index as? PtIdentifier
|
||||||
} else {
|
if(indexVar!=null) {
|
||||||
// assign regular array indexing
|
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y")
|
||||||
if (target.constArrayIndexValue!=null) {
|
} else {
|
||||||
when (register) {
|
require(target.array.index.type in ByteDatatypes)
|
||||||
CpuRegister.A -> {}
|
asmgen.saveRegisterStack(register, false)
|
||||||
CpuRegister.X -> asmgen.out(" txa")
|
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false)
|
||||||
CpuRegister.Y -> asmgen.out(" tya")
|
asmgen.out(" pla | sta ${target.asmVarname},y")
|
||||||
}
|
|
||||||
asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
when (register) {
|
|
||||||
CpuRegister.A -> {}
|
|
||||||
CpuRegister.X -> asmgen.out(" txa")
|
|
||||||
CpuRegister.Y -> asmgen.out(" tya")
|
|
||||||
}
|
|
||||||
val indexVar = target.array.index as? PtIdentifier
|
|
||||||
if(indexVar!=null) {
|
|
||||||
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y")
|
|
||||||
} else {
|
|
||||||
require(target.array.index.type in ByteDatatypes)
|
|
||||||
asmgen.saveRegisterStack(register, false)
|
|
||||||
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false)
|
|
||||||
asmgen.out(" pla | sta ${target.asmVarname},y")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3632,21 +3518,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
storeRegisterAInMemoryAddress(target.memory!!)
|
storeRegisterAInMemoryAddress(target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
if(assignsIndexedPointerVar(target)) {
|
|
||||||
if (target.constArrayIndexValue==0u) {
|
|
||||||
asmgen.out(" lda #0")
|
|
||||||
asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable)
|
|
||||||
} else {
|
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y)
|
|
||||||
if (asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
|
||||||
asmgen.out(" lda #0 | sta (${target.asmVarname}),y")
|
|
||||||
} else {
|
|
||||||
asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1")
|
|
||||||
asmgen.out(" lda #0 | sta (P8ZP_SCRATCH_W2),y")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(target.array!!.splitWords)
|
if(target.array!!.splitWords)
|
||||||
throw AssemblyError("cannot assign byte to split word array here ${target.position}")
|
throw AssemblyError("cannot assign byte to split word array here ${target.position}")
|
||||||
if (target.constArrayIndexValue!=null) {
|
if (target.constArrayIndexValue!=null) {
|
||||||
@@ -3686,21 +3557,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
storeRegisterAInMemoryAddress(target.memory!!)
|
storeRegisterAInMemoryAddress(target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
if(assignsIndexedPointerVar(target)) {
|
|
||||||
if (target.constArrayIndexValue==0u) {
|
|
||||||
asmgen.out(" lda #${byte.toHex()}")
|
|
||||||
asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable)
|
|
||||||
} else {
|
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y)
|
|
||||||
if (asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
|
||||||
asmgen.out(" lda #${byte.toHex()} | sta (${target.asmVarname}),y")
|
|
||||||
} else {
|
|
||||||
asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1")
|
|
||||||
asmgen.out(" lda #${byte.toHex()} | sta (P8ZP_SCRATCH_W2),y")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(target.array!!.splitWords)
|
if(target.array!!.splitWords)
|
||||||
TODO("assign into split words ${target.position}")
|
TODO("assign into split words ${target.position}")
|
||||||
if (target.constArrayIndexValue!=null) {
|
if (target.constArrayIndexValue!=null) {
|
||||||
@@ -3732,9 +3588,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignsIndexedPointerVar(target: AsmAssignTarget): Boolean =
|
|
||||||
target.origAstTarget?.array?.variable?.type==DataType.UWORD
|
|
||||||
|
|
||||||
internal fun assignConstantFloat(target: AsmAssignTarget, float: Double) {
|
internal fun assignConstantFloat(target: AsmAssignTarget, float: Double) {
|
||||||
if (float == 0.0) {
|
if (float == 0.0) {
|
||||||
// optimized case for float zero
|
// optimized case for float zero
|
||||||
|
@@ -163,7 +163,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.assignExpressionTo(memory.address, AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UWORD, memory.definingISub(), target.position, register = RegisterOrPair.AY))
|
asmgen.assignExpressionToRegister(memory.address, RegisterOrPair.AY, false)
|
||||||
asmgen.saveRegisterStack(CpuRegister.A, true)
|
asmgen.saveRegisterStack(CpuRegister.A, true)
|
||||||
asmgen.saveRegisterStack(CpuRegister.Y, true)
|
asmgen.saveRegisterStack(CpuRegister.Y, true)
|
||||||
asmgen.out(" jsr prog8_lib.read_byte_from_address_in_AY_into_A")
|
asmgen.out(" jsr prog8_lib.read_byte_from_address_in_AY_into_A")
|
||||||
|
@@ -302,25 +302,6 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
val variable = targetArray.variable.name
|
val variable = targetArray.variable.name
|
||||||
val itemsize = codeGen.program.memsizer.memorySize(targetArray.type)
|
val itemsize = codeGen.program.memsizer.memorySize(targetArray.type)
|
||||||
|
|
||||||
if(targetArray.usesPointerVariable) {
|
|
||||||
if(itemsize!=1)
|
|
||||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
|
||||||
if(targetArray.index.type!=DataType.UBYTE)
|
|
||||||
throw AssemblyError("non-array var indexing requires bytes index")
|
|
||||||
val tr = expressionEval.translateExpression(targetArray.index)
|
|
||||||
val idxReg = tr.resultReg
|
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
|
||||||
val code = IRCodeChunk(null, null)
|
|
||||||
if(zero) {
|
|
||||||
// there's no STOREZIX instruction
|
|
||||||
valueRegister = codeGen.registers.nextFree()
|
|
||||||
code += IRInstruction(Opcode.LOAD, targetDt, reg1=valueRegister, immediate = 0)
|
|
||||||
}
|
|
||||||
code += IRInstruction(Opcode.STOREIX, targetDt, reg1=valueRegister, reg2=idxReg, labelSymbol = variable)
|
|
||||||
result += code
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
val fixedIndex = constIntValue(targetArray.index)
|
val fixedIndex = constIntValue(targetArray.index)
|
||||||
val arrayLength = codeGen.symbolTable.getLength(targetArray.variable.name)
|
val arrayLength = codeGen.symbolTable.getLength(targetArray.variable.name)
|
||||||
if(zero) {
|
if(zero) {
|
||||||
|
@@ -705,7 +705,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is PtArrayIndexer -> {
|
is PtArrayIndexer -> {
|
||||||
require(!target.usesPointerVariable)
|
|
||||||
if(target.splitWords) {
|
if(target.splitWords) {
|
||||||
// lsb/msb in split arrays, element index 'size' is always 1
|
// lsb/msb in split arrays, element index 'size' is always 1
|
||||||
val constIndex = target.index.asConstInteger()
|
val constIndex = target.index.asConstInteger()
|
||||||
|
@@ -180,19 +180,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val vmDt = irType(arrayIx.type)
|
val vmDt = irType(arrayIx.type)
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val arrayVarSymbol = arrayIx.variable.name
|
val arrayVarSymbol = arrayIx.variable.name
|
||||||
|
|
||||||
if(arrayIx.usesPointerVariable) {
|
|
||||||
if(eltSize!=1)
|
|
||||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
|
||||||
if(arrayIx.index.type !in ByteDatatypes)
|
|
||||||
throw AssemblyError("non-array var indexing requires bytes index")
|
|
||||||
val tr = translateExpression(arrayIx.index)
|
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
|
||||||
val resultReg = codeGen.registers.nextFree()
|
|
||||||
addInstr(result, IRInstruction(Opcode.LOADIX, vmDt, reg1=resultReg, reg2=tr.resultReg, labelSymbol = arrayVarSymbol), null)
|
|
||||||
return ExpressionCodeResult(result, vmDt, resultReg, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
var resultRegister = -1
|
var resultRegister = -1
|
||||||
|
|
||||||
if(arrayIx.splitWords) {
|
if(arrayIx.splitWords) {
|
||||||
@@ -1253,20 +1240,17 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(array.splitWords)
|
if(array.splitWords)
|
||||||
return operatorMinusInplaceSplitArray(array, operand)
|
return operatorMinusInplaceSplitArray(array, operand)
|
||||||
if(array.usesPointerVariable) {
|
val eltDt = irType(array.type)
|
||||||
TODO("inplace - for pointer variable")
|
|
||||||
}
|
|
||||||
val vmDt = irType(array.type)
|
|
||||||
val constIndex = array.index.asConstInteger()
|
val constIndex = array.index.asConstInteger()
|
||||||
val constValue = operand.asConstInteger()
|
val constValue = operand.asConstInteger()
|
||||||
if(constIndex!=null && constValue!=null) {
|
if(constIndex!=null && constValue!=null) {
|
||||||
if(constValue==1) {
|
if(constValue==1) {
|
||||||
addInstr(result, IRInstruction(Opcode.DECM, vmDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
addInstr(result, IRInstruction(Opcode.DECM, eltDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
||||||
} else {
|
} else {
|
||||||
val valueReg=codeGen.registers.nextFree()
|
val valueReg=codeGen.registers.nextFree()
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate = constValue)
|
it += IRInstruction(Opcode.LOAD, eltDt, reg1=valueReg, immediate = constValue)
|
||||||
it += IRInstruction(Opcode.SUBM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
it += IRInstruction(Opcode.SUBM, eltDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(result)
|
return Ok(result)
|
||||||
@@ -1344,9 +1328,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(array.splitWords)
|
if(array.splitWords)
|
||||||
return operatorPlusInplaceSplitArray(array, operand)
|
return operatorPlusInplaceSplitArray(array, operand)
|
||||||
if(array.usesPointerVariable) {
|
|
||||||
TODO("inplace + for pointer variable")
|
|
||||||
}
|
|
||||||
val eltSize = codeGen.program.memsizer.memorySize(array.type)
|
val eltSize = codeGen.program.memsizer.memorySize(array.type)
|
||||||
val elementDt = irType(array.type)
|
val elementDt = irType(array.type)
|
||||||
val constIndex = array.index.asConstInteger()
|
val constIndex = array.index.asConstInteger()
|
||||||
@@ -1806,8 +1787,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(array.splitWords)
|
if(array.splitWords)
|
||||||
TODO("inplace compare for split word array")
|
TODO("inplace compare for split word array")
|
||||||
if(array.usesPointerVariable)
|
|
||||||
TODO("inplace compare for pointer variable")
|
|
||||||
val vmDt = irType(array.type)
|
val vmDt = irType(array.type)
|
||||||
val constIndex = array.index.asConstInteger()
|
val constIndex = array.index.asConstInteger()
|
||||||
val constValue = value.asConstInteger()
|
val constValue = value.asConstInteger()
|
||||||
|
@@ -1534,20 +1534,7 @@ class IRCodeGen(
|
|||||||
val itemsize = program.memsizer.memorySize(array.type)
|
val itemsize = program.memsizer.memorySize(array.type)
|
||||||
val fixedIndex = constIntValue(array.index)
|
val fixedIndex = constIntValue(array.index)
|
||||||
if(fixedIndex!=null) {
|
if(fixedIndex!=null) {
|
||||||
val offset = fixedIndex*itemsize
|
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = variable, symbolOffset = fixedIndex*itemsize), null)
|
||||||
val indexReg = registers.nextFree()
|
|
||||||
val dataReg = registers.nextFree()
|
|
||||||
if(array.usesPointerVariable) {
|
|
||||||
// we don't have an indirect dec/inc so do it via an intermediate register
|
|
||||||
result += IRCodeChunk(null,null).also {
|
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = indexReg, immediate = offset)
|
|
||||||
it += IRInstruction(Opcode.LOADIX, irDt, reg1 = dataReg, reg2 = indexReg, labelSymbol = variable)
|
|
||||||
it += IRInstruction(operationRegister, irDt, reg1=dataReg)
|
|
||||||
it += IRInstruction(Opcode.STOREIX, irDt, reg1 = dataReg, reg2 = indexReg, labelSymbol = variable)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = variable, symbolOffset = offset), null)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val indexTr = expressionEval.translateExpression(array.index)
|
val indexTr = expressionEval.translateExpression(array.index)
|
||||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
addToResult(result, indexTr, indexTr.resultReg, -1)
|
||||||
@@ -1555,15 +1542,9 @@ class IRCodeGen(
|
|||||||
result += multiplyByConst(IRDataType.BYTE, indexTr.resultReg, itemsize)
|
result += multiplyByConst(IRDataType.BYTE, indexTr.resultReg, itemsize)
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
val incReg = registers.nextFree()
|
val incReg = registers.nextFree()
|
||||||
if(array.usesPointerVariable) {
|
it += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||||
it += IRInstruction(Opcode.LOADIX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
it += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||||
it += IRInstruction(operationRegister, irDt, reg1=incReg)
|
it += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||||
it += IRInstruction(Opcode.STOREIX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
|
||||||
} else {
|
|
||||||
it += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
|
||||||
it += IRInstruction(operationRegister, irDt, reg1=incReg)
|
|
||||||
it += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@@ -195,25 +195,22 @@ _after:
|
|||||||
// replace pointervar[word] by @(pointervar+word) to avoid the
|
// replace pointervar[word] by @(pointervar+word) to avoid the
|
||||||
// "array indexing is limited to byte size 0..255" error for pointervariables.
|
// "array indexing is limited to byte size 0..255" error for pointervariables.
|
||||||
val indexExpr = arrayIndexedExpression.indexer.indexExpr
|
val indexExpr = arrayIndexedExpression.indexer.indexExpr
|
||||||
val indexerDt = indexExpr.inferType(program)
|
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
|
||||||
if(indexerDt.isWords) {
|
if(arrayVar!=null && arrayVar.datatype==DataType.UWORD) {
|
||||||
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
|
val add: Expression =
|
||||||
if(arrayVar!=null && arrayVar.datatype==DataType.UWORD) {
|
if(indexExpr.constValue(program)?.number==0.0)
|
||||||
val add: Expression =
|
arrayIndexedExpression.arrayvar.copy()
|
||||||
if(indexExpr.constValue(program)?.number==0.0)
|
else
|
||||||
arrayIndexedExpression.arrayvar.copy()
|
BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexExpr, arrayIndexedExpression.position)
|
||||||
else
|
return if(parent is AssignTarget) {
|
||||||
BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexExpr, arrayIndexedExpression.position)
|
// assignment to array
|
||||||
return if(parent is AssignTarget) {
|
val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position)
|
||||||
// assignment to array
|
val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position)
|
||||||
val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position)
|
listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent))
|
||||||
val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position)
|
} else {
|
||||||
listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent))
|
// read from array
|
||||||
} else {
|
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
||||||
// read from array
|
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
||||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
|
||||||
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return noModifications
|
return noModifications
|
||||||
|
@@ -551,8 +551,10 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun transform(srcArr: ArrayIndexedExpression): PtArrayIndexer {
|
private fun transform(srcArr: ArrayIndexedExpression): PtArrayIndexer {
|
||||||
val arrayVarType = srcArr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
if(srcArr.arrayvar.targetVarDecl(program)!!.datatype !in ArrayDatatypes + DataType.STR)
|
||||||
val array = PtArrayIndexer(arrayVarType, srcArr.position)
|
throw FatalAstException("array indexing can be used on array or string variables ${srcArr.position}")
|
||||||
|
val eltType = srcArr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||||
|
val array = PtArrayIndexer(eltType, srcArr.position)
|
||||||
array.add(transform(srcArr.arrayvar))
|
array.add(transform(srcArr.arrayvar))
|
||||||
array.add(transformExpression(srcArr.indexer.indexExpr))
|
array.add(transformExpression(srcArr.indexer.indexExpr))
|
||||||
return array
|
return array
|
||||||
|
@@ -288,9 +288,6 @@ mylabel:
|
|||||||
|
|
||||||
test("nesting with overlapping names is ok (doesn't work for 64tass)") {
|
test("nesting with overlapping names is ok (doesn't work for 64tass)") {
|
||||||
val src="""
|
val src="""
|
||||||
%import textio
|
|
||||||
%zeropage basicsafe
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
main()
|
main()
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
petaxian is now a lot larger since pointer[idx] is rewritten into @(ptr+idx). Missing some optimized code somewhere now?
|
||||||
|
VM textelite is now a lot larger too
|
||||||
|
|
||||||
(after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type.
|
(after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type.
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@@ -1,74 +1,30 @@
|
|||||||
%import textio
|
%import textio
|
||||||
;; %import test_stack
|
%import floats
|
||||||
|
%import math
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
uword[3] a
|
sub derp(str arg) {
|
||||||
uword[3] b
|
arg[4] = '?'
|
||||||
ubyte @shared j
|
|
||||||
uword @shared aa = 1
|
|
||||||
|
|
||||||
sub derp() {
|
|
||||||
return aa=5
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
derp()
|
str msg = "hello"
|
||||||
;; test_stack.test()
|
derp(msg)
|
||||||
j = 1
|
txt.chrout(msg[4]) ; ?
|
||||||
a[j] = 1
|
|
||||||
b[j] = 0
|
|
||||||
b[j] += 5 * aa
|
|
||||||
b[j] += 5 * aa
|
|
||||||
b[j] += 5 * aa
|
|
||||||
b[j] += 5 * aa
|
|
||||||
txt.print_uw(b[j]) ; 20
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
b[j] += 5 * a[1]
|
uword @shared az = $4000
|
||||||
b[j] += 5 * a[1]
|
@($4004) = 0
|
||||||
b[j] += 5 * a[1]
|
az[4] |= $40
|
||||||
b[j] += 5 * a[1]
|
txt.print_ub(@($4004)) ; 64
|
||||||
txt.print_uw(b[j]) ; 40
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
b[j] += 5 * a[j]
|
@(az+4) = 0
|
||||||
b[j] += 5 * a[j]
|
@(az+4) |= $4f
|
||||||
b[j] += 5 * a[j]
|
txt.print_ub(@($4004)) ; 79
|
||||||
b[j] += 5 * a[j]
|
|
||||||
txt.print_uw(b[j]) ; 60
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
;; test_stack.test()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
;%import textio
|
|
||||||
;%import floats
|
|
||||||
;%zeropage basicsafe
|
|
||||||
;%option no_sysinit
|
|
||||||
;
|
|
||||||
;main {
|
|
||||||
; sub start() {
|
|
||||||
|
|
||||||
; uword @shared addr = 2000
|
|
||||||
; @(2000) = 199
|
|
||||||
; txt.print_ub(@(2000))
|
|
||||||
; txt.nl()
|
|
||||||
; @(addr) = ~@(addr)
|
|
||||||
; txt.print_ub(@(2000))
|
|
||||||
; txt.nl()
|
|
||||||
;
|
|
||||||
; word[3] @split @shared array = [1111,$10ff,3333]
|
|
||||||
;
|
|
||||||
; txt.print_w(array[1])
|
|
||||||
; txt.nl()
|
|
||||||
; txt.print_w(-array[1])
|
|
||||||
; txt.nl()
|
|
||||||
; array[1] = -array[1]
|
|
||||||
; txt.print_w(array[1])
|
|
||||||
; txt.nl()
|
|
||||||
; txt.nl()
|
|
||||||
;
|
|
||||||
; ubyte @shared idx = 1
|
; ubyte @shared idx = 1
|
||||||
; txt.print_w(array[idx])
|
; txt.print_w(array[idx])
|
||||||
; txt.nl()
|
; txt.nl()
|
||||||
@@ -151,5 +107,5 @@ main {
|
|||||||
; bb = bb or barr[1]
|
; bb = bb or barr[1]
|
||||||
; bb = bb xor barr[1]
|
; bb = bb xor barr[1]
|
||||||
; bb = not bb
|
; bb = not bb
|
||||||
; }
|
}
|
||||||
;}
|
}
|
||||||
|
Reference in New Issue
Block a user