mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
Merge branch 'remove_evalstack'
# Conflicts: # codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt
This commit is contained in:
commit
1ae950a638
@ -118,6 +118,9 @@ class PtArrayIndexer(elementType: DataType, position: Position): PtExpression(el
|
||||
val splitWords: Boolean
|
||||
get() = variable.type in SplitWordArrayTypes
|
||||
|
||||
val usesPointerVariable: Boolean
|
||||
get() = variable.type==DataType.UWORD
|
||||
|
||||
init {
|
||||
require(elementType in NumericDatatypes)
|
||||
}
|
||||
|
@ -90,7 +90,24 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
||||
if(constIndex!=null) {
|
||||
val indexValue = constIndex * program.memsizer.memorySize(elementDt)
|
||||
when(elementDt) {
|
||||
in ByteDatatypes -> asmgen.out(if (incr) " inc $asmArrayvarname+$indexValue" else " dec $asmArrayvarname+$indexValue")
|
||||
in ByteDatatypes -> {
|
||||
if(targetArrayIdx.usesPointerVariable) {
|
||||
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 -> {
|
||||
if(incr)
|
||||
asmgen.out(" inc $asmArrayvarname+$indexValue | bne + | inc $asmArrayvarname+$indexValue+1 |+")
|
||||
@ -113,7 +130,22 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.X)
|
||||
when(elementDt) {
|
||||
in ByteDatatypes -> {
|
||||
asmgen.out(if(incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
||||
if(targetArrayIdx.usesPointerVariable) {
|
||||
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 -> {
|
||||
if(incr)
|
||||
@ -123,8 +155,7 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
||||
lda $asmArrayvarname,x
|
||||
bne +
|
||||
dec $asmArrayvarname+1,x
|
||||
+ dec $asmArrayvarname,x
|
||||
""")
|
||||
+ dec $asmArrayvarname,x""")
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
asmgen.out("""
|
||||
|
@ -61,8 +61,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
val elementDt = assign.source.datatype
|
||||
val arrayVarName = asmgen.asmVariableName(value.variable)
|
||||
|
||||
if(value.variable.type==DataType.UWORD) {
|
||||
// indexing a pointer var instead of a real array or string
|
||||
if(value.usesPointerVariable) {
|
||||
if(elementDt !in ByteDatatypes)
|
||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||
if(value.type != DataType.UBYTE)
|
||||
@ -2267,14 +2266,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(target.origAstTarget?.array?.variable?.type==DataType.UWORD) {
|
||||
// assigning an indexed pointer var
|
||||
if(assignsIndexedPointerVar(target)) {
|
||||
if (target.constArrayIndexValue==0u) {
|
||||
asmgen.out(" lda $sourceName")
|
||||
asmgen.storeAIntoPointerVar(target.origAstTarget.array!!.variable)
|
||||
asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable)
|
||||
} else {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
|
||||
if (asmgen.isZpVar(target.origAstTarget.array!!.variable)) {
|
||||
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")
|
||||
@ -2489,15 +2487,14 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
TODO("assign register as word into Array not yet supported")
|
||||
if(target.array!!.splitWords)
|
||||
TODO("assign register into split words ${target.position}")
|
||||
if(target.origAstTarget?.array?.variable?.type==DataType.UWORD) {
|
||||
// assigning an indexed pointer var
|
||||
if(assignsIndexedPointerVar(target)) {
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
if(asmgen.isZpVar(target.origAstTarget.array!!.variable)) {
|
||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" ldy #${target.constArrayIndexValue} | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
@ -2516,7 +2513,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
val indexVar = target.array.index as PtIdentifier
|
||||
if(asmgen.isZpVar(target.origAstTarget.array!!.variable)) {
|
||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
@ -2987,14 +2984,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(target.origAstTarget?.array?.variable?.type==DataType.UWORD) {
|
||||
// assigning an indexed pointer var
|
||||
if(assignsIndexedPointerVar(target)) {
|
||||
if (target.constArrayIndexValue==0u) {
|
||||
asmgen.out(" lda #0")
|
||||
asmgen.storeAIntoPointerVar(target.origAstTarget.array!!.variable)
|
||||
asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable)
|
||||
} else {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
|
||||
if (asmgen.isZpVar(target.origAstTarget.array!!.variable)) {
|
||||
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")
|
||||
@ -3042,14 +3038,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(target.origAstTarget?.array?.variable?.type==DataType.UWORD) {
|
||||
// assigning an indexed pointer var
|
||||
if(assignsIndexedPointerVar(target)) {
|
||||
if (target.constArrayIndexValue==0u) {
|
||||
asmgen.out(" lda #${byte.toHex()}")
|
||||
asmgen.storeAIntoPointerVar(target.origAstTarget.array!!.variable)
|
||||
asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable)
|
||||
} else {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
|
||||
if (asmgen.isZpVar(target.origAstTarget.array!!.variable)) {
|
||||
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")
|
||||
@ -3095,6 +3090,9 @@ 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) {
|
||||
if (float == 0.0) {
|
||||
// optimized case for float zero
|
||||
|
@ -198,8 +198,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val variable = targetArray.variable.name
|
||||
val itemsize = codeGen.program.memsizer.memorySize(targetArray.type)
|
||||
|
||||
if(targetArray.variable.type==DataType.UWORD) {
|
||||
// indexing a pointer var instead of a real array or string
|
||||
if(targetArray.usesPointerVariable) {
|
||||
if(itemsize!=1)
|
||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||
if(targetArray.index.type!=DataType.UBYTE)
|
||||
|
@ -147,8 +147,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val arrayVarSymbol = arrayIx.variable.name
|
||||
|
||||
if(arrayIx.variable.type==DataType.UWORD) {
|
||||
// indexing a pointer var instead of a real array or string
|
||||
if(arrayIx.usesPointerVariable) {
|
||||
if(eltSize!=1)
|
||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||
if(arrayIx.index.type!=DataType.UBYTE)
|
||||
|
@ -1469,7 +1469,19 @@ class IRCodeGen(
|
||||
val fixedIndex = constIntValue(array.index)
|
||||
if(fixedIndex!=null) {
|
||||
val offset = fixedIndex*itemsize
|
||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol="$variable+$offset"), 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+$offset"), null)
|
||||
}
|
||||
} else {
|
||||
val indexTr = expressionEval.translateExpression(array.index)
|
||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
||||
@ -1477,9 +1489,15 @@ class IRCodeGen(
|
||||
result += multiplyByConst(IRDataType.BYTE, indexTr.resultReg, itemsize)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val incReg = registers.nextFree()
|
||||
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)
|
||||
if(array.usesPointerVariable) {
|
||||
it += IRInstruction(Opcode.LOADIX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
it += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||
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
|
||||
|
@ -1,16 +1,23 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
ubyte var = 0
|
||||
ubyte[2] data = [100, 100]
|
||||
uword dRef = &data
|
||||
|
||||
when var {
|
||||
1 -> txt.print("one")
|
||||
2 -> txt.print("two")
|
||||
0 -> {
|
||||
}
|
||||
else -> txt.print("other")
|
||||
}
|
||||
}
|
||||
sub start() {
|
||||
dRef[0]--
|
||||
dRef[1]++
|
||||
|
||||
cx16.r0L = 0
|
||||
cx16.r1L = 1
|
||||
dRef[cx16.r0L]--
|
||||
dRef[cx16.r1L]++
|
||||
|
||||
txt.print_ub(data[0])
|
||||
txt.spc()
|
||||
txt.print_ub(data[1])
|
||||
|
||||
repeat {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user